为什么需要在脚本文件的开头放置#!/ bin / bash?


483

我之前已经制作过Bash脚本,它们运行良好,没有#!/bin/bash开始的情况。

放入它有什么意义?事情会有所不同吗?

另外,您如何发音#?我知道这!发音为“砰”。

怎么#!发音?


8
除非别无选择,否则您不需要,也不需要。尽可能使用'#!/ bin / sh',了解(POSIX)shell和bash之间的区别。一天之后,您的简历就会变得更长,这时您会发现自己身处具有不同Shell的系统上,但仍然希望脚本能够正常工作。
詹斯2012年

50
它的发音为“ Hash-Bang”或“ She-Bang”。
海滨别墅

22
我认为值得注意的是,仅当您将脚本作为可执行文件运行时才执行。因此,如果您设置了可执行标志,然后键入./yourscript.extension,例如./helloworld.py./helloworld.sh,它将在该行的第一行寻找解释器,该行将是#!/bin/python!#/bin/bash,而在执行脚本如时python helloworld.py,将不会观察到第一行,因为它已被注释出来。因此,这是壳/内核的特殊序列。
JFA 2015年

@JFA在将!#用于python和#!时,bash和python之间的顺序有所变化。为了b?
AAI

@AjeyaAnand不,这是一个错误的类型,很好的捕获
JFA

Answers:


425

这是一个约定,因此* nix shell知道要运行哪种解释器。

例如,ATT的较旧版本默认为sh(Bourne shell),而BSD的较旧版本默认为csh(C shell)。

即使在今天(大多数系统都运行bash,即“ Bourne Again Shell”),脚本仍可以使用bash,python,perl,ruby,PHP等。例如,您可能会看到#!/bin/perl#!/bin/perl5

PS:感叹号(!)亲切地称为“ bang”。shell注释符号(#)有时称为“ hash”

PPS:请记住-在* nix下,将后缀与文件类型相关联只是一种约定,而不是“规则”。一个可执行文件可以是一个二进制程序,一百万脚本类型和其他的东西,以及任何一个。因此需要#!/bin/bash


1
我发现了其他有用的东西,$#。那叫什么
节点忍者

91
shebang不是shell约定,它是内核在处理execve(2)syscall 时解释的;所以shebang是内核约定,而不是shell约定。
Basile Starynkevitch 2012年

10
此外,如果文件没有扩展名,它还可以帮助Vim等编辑器确定语法突出显示的语言。如果没有shebang,Vim将显示与纯文本文件相同的bash脚本。
亚伦·布伦库什

1
这让我想知道你是否需要添加#!/bin/sh到喜欢的东西.profile和东西,运行为onload
科罗布峡谷

5
所以... hash-bang-slash-bin-slash-bash吗?
伯纳特

134

更准确地说,shebang #!可执行文件x 模式文件)的前两个字节,由execve(2)系统调用(执行程序)解释。但是POSIX规范execve没有提及shebang。

它必须后跟解释器可执行文件的文件路径(BTW甚至可以是相对的,但大多数情况下是绝对的)。

在用户中找到解释器(例如)的一个不错的技巧(也许不是那么好)是使用程序(始终在所有Linux上),例如python$PATHenv/usr/bin/env

 #!/usr/bin/env python

任何ELF可执行文件都可以是解释器。您甚至可以使用,#!/bin/cat或者#!/bin/true如果您愿意!(但这通常是无用的)


8
有关#!/usr/bin/env黑客的讨论,请参见此问题。
基思·汤普森

如果我想将参数传递给python,我该如何实际执行我想执行的操作#!/usr/bin/env bash -x。我怎么做 ?
indianwebdevil

它很简单,我自己找到了它,只是在此之后添加了参数#!/usr/bin/env bash -x
indianwebdevil

bash几乎总是在,/bin/bash所以您的#!/bin/bash -x
爆炸

49

叫做舍邦。在unix-speak中,#称为Sharp(如音乐中的)或hash(如Twitter上的标签),以及!叫做爆炸。(您实际上可以使用!!来引用先前的shell命令,称为bang-bang)。因此,当放在一起时,您会得到haSH-BANG或shebang。

#之后的部分!告诉Unix使用什么程序来运行它。如果未指定,它将尝试使用bash(或sh,zsh或任何$ SHELL变量),但是如果存在,它将使用该程序。另外,#是大多数语言的注释,因此该行在后续执行中将被忽略。


2
如果我已经在bash中,如果看到#!/ bin / bash,它将启动另一个bash实例吗?如果我已经参加了bash比赛,该怎么办?有什么区别吗?
节点忍者

2
@javascriptninja会以任何方式启动新的bash shell。就bash而言,只要您已经在使用bash,就没有任何区别。shebang仅在以下情况下才真正重要:(a)您需要运行的不只是shell,例如python或perl,或者(b)您不使用bash shell(即,使用zsh),但是您需要运行需要在bash中运行的内容。
austin1howard 2012年

但是,在我看来,包括shebang是一个很好的做法,这样一来,阅读代码的人就会知道发生了什么。
austin1howard

2
错误:execve(2)syscall不要使用$SHELL变量。解释shebang的是内核。
Basile Starynkevitch 2012年

1
@BasileStarynkevitch是正确的,内核中的elf加载程序解释了shebang。我说的是,如果不提供shebang,将使用$ SHELL。
austin1howard 2012年

19

家当是一个指令加载器使用的是后指定的程序#!,当您尝试执行它解释为有问题的文件。所以,如果你尝试运行一个名为foo.sh其具有#!/bin/bash顶部,实际的命令运行的/bin/bash foo.sh。这是对不同程序使用不同解释器的灵活方式。这是在系统级别实现的,而用户级别的API是shebang约定。

值得一提的是,shebang是一个神奇的数字 -一个人类可读的数字,它将文件标识为给定解释器的脚本。

即使没有shebang,您对它的看法也是“有效的”,这仅是因为所讨论的程序是为与您使用的shell相同的shell编写的shell脚本。例如,您可以很好地编写一个javascript文件,然后放一个#! /usr/bin/js(或类似的东西)以拥有一个javascript“ Shell脚本”。



15

每个发行版都有一个默认的外壳程序。Bash是大多数系统上的默认设置。如果您碰巧在具有不同默认Shell的系统上工作,则这些脚本如果专门针对Bash编写,则可能无法按预期工作。

多年来,Bash不断发展壮大,从ksh和那里获取代码sh

添加#!/bin/bash为脚本的第一行,告诉操作系统调用指定shell的命令来执行脚本中的命令。

#! 通常称为“哈希爆炸”,“她爆炸”或“ sha-bang”。


9

叫做舍邦。它由数字符号和感叹号字符(#!)组成,后跟解释器的完整路径,例如/ bin / bash。UNIX和Linux下的所有脚本都使用第一行中指定的解释器执行。



0

对于使用其他没有该库的系统的人来说,这可能很有用。如果未声明,并且脚本中有该系统不支持的某些功能,则应声明#/ bin / bash。在工作之前,我曾遇到过这个问题,现在我只是将其作为一种练习。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.