爱技术 & 爱分享
爱蛋蛋 & 爱生活

shebang (#!)

shebang

什么是shebang?

我们写一个shell脚本时,总是习惯在最前面加上一行 #!/bin/bash,它就是脚本的shebang。

官方一点的说法就是:

在计算机科学中,Shebang是一个由井号和叹号构成的字符串行,其出现在文本文件的第一行的前两个字符。 在文件中存在Shebang的情况下,类Unix操作系统的程序载入器会分析Shebang后的内容,将这些内容作为解释器指令,并调用该指令,并将载有Shebang的文件路径作为该解释器的参数。

至于为什么叫这么个奇怪的名字,Wikipedia上这样解释的:

Shebang 的名字来自于 SHArp 和 bang,或 haSH bang 的缩写,指代 Shebang 中 #! 两个符号的典型 Unix 名称。 Unix 术语中,井号通常称为 sharp,hash 或 mesh;而叹号则常常称为 bang。也有看法认为,shebang 名字中的 sh 来自于默认shell Bourne shell 的名称,sh,因为常常使用 shebang 调用之。
在2010年版的 Advanced bash scripting guide(revision 6.2)中,shebang 被称为 “sha-bang”,同时提到”也写作 she-bang 或 sh-bang”,但该文件中没有提到 “shebang” 这一形式。

C语言和Unix的开发者丹尼斯·里奇在被问及他会如何称呼这一特性时,他答道:

我不记得我们曾经给它取过一个适当的名字。导入这一特性已经是相当晚了–我觉得我是从关于伯克利Unix的UCB会议上的某人那里得到的这一灵感;我可能是首先实现它的人之一,但这个创意是来自于别人的。
至于它的名字:可能是类似于”hash-bang”的英国风描述性文字,但我没有在任何场合使用类似宠物的名字来描述它。

还有一个有趣的解释在这里:http://whatis.techtarget.com/definition/shebang

语法特性:

Shebang 这一语法特性由 #! 开头,即井号和叹号。 在开头字符之后,可以有一个或数个空白字符,后接解释器的绝对路径,用于调用解释器。 在直接调用脚本时,调用者会利用 Shebang 提供的信息调用相应的解释器,从而使得脚本文件的调用方式与普通的可执行文件类似。

下面列出了一些典型的 shebang 解释器指令:

#!/bin/sh—使用 sh,即 Bourne shell 或其它兼容 shell 执行脚本
#!/bin/csh—使用 csh,即 C shell 执行
#!/usr/bin/perl -w—使用带警告的 Perl 执行
#!/usr/bin/python -O—使用具有代码优化的 Python 执行
#!/usr/bin/php—使用 PHP 的命令行解释器执行

在许多系统上,/bin/sh 是链接到 Bash 的,而 /bin/csh 则是链接到 tcsh 的,因此设定前面的解释器实际上是运行的与之兼容的,或改进的版本。

Shebang 行也可以包含需要传递到解释器的特定选项(参数)。然而,选项传递的方式随实现的不同而不同。

解释器指令允许脚本和数据文件充当系统命令,无需在调用时由用户指定解释器,从而对用户和其它程序隐藏其实现细节。

假设 /usr/local/bin/foo 中有一以下行开头的 Bourne shell 脚本

#!/bin/sh -x

而它被如此调用(”$”是命令提示符)

$ foo bar
该命令的输出等同于

$ /bin/sh -x /usr/local/bin/foo bar

除了 argv[0] 被设定为脚本的文件名,而非解释器的文件名外。

由于 sh 从其命令行指定的文件中读取命令,上面的命令就会执行 /usr/local/bin/foo 中的命令,同时,将 bar作为foo 命令的参数 $1。

由于shebang开头的井号也是Bourne shell和许多其它解释性语言的注释符,因此在这些语言中,解释器指令本身会被解释器认为是单纯的注释而跳过。 然而,并不是每一种解释器都会自动忽略shebang行,例如对于下面的脚本,

#!/bin/cat
Hello world!

cat 会把文件中的两行都输出到标准输出中。

使用 #!/usr/bin/env 脚本解释器名称 是一种常见的在不同平台上都能正确找到解释器的办法。

Linux的操作系统的文件一般是UTF-8编码。如果脚本文件是以 UTF-8 的 BOM(0xEF 0xBB 0xBF) 开头的,那么 exec 函数将不会启动 shebang 指定的解释器来执行该脚本。因此,Linux 的脚本文件不应在文件开头包含 UTF-8 的 BOM。

需要注意的是:在指定脚本解释器来执行脚本时,shebang会被指定的脚本解释器覆盖,即优先使用指定的脚本解释器来执行脚本(习惯性地用sh ./test.sh 会提示 command not found)

赞(0) 传送门
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。编程日志 » shebang (#!)
分享到: 更多 (0)

游戏 && 后端

传送门传送门