在shell脚本编程中,"#!/bin/sh"的用途/含义是什么?

35
“#!/bin/sh”是shell脚本中的一行特殊注释,它指定了脚本所使用的解释器类型。这行注释告诉系统需要使用/bin/sh来解释执行该脚本。即使在被注释掉的情况下,它也会生效。

请参阅:https://zh.wikipedia.org/wiki/Shebang - Felix Kling
5
这可能是关于UNIX shell脚本中 "#!/bin/sh" 这行代码的重复问题。该行代码指定了要使用的shell程序,并且在脚本运行时会调用它。 - Keith Thompson
http://theunixshell.blogspot.com/search/label/shebang - Vijay
5个回答

35
在脚本开头的 sha-bang (#!) [1] 告诉你的系统,这个文件是一组要传递给指定命令解释器的命令。#! 实际上是一个两个字节[2]的魔数,一个特殊标记,指定了文件类型,或者在这种情况下是可执行的 shell 脚本(关于这个有趣主题的更多详细信息,请参阅 man magic)。紧接着 sha-bang 的是路径名。这是解释脚本中的命令的程序的路径,无论是 shell、编程语言还是实用程序。然后,该命令解释器执行脚本中的命令,从顶部开始(在 sha-bang 行之后的行),并忽略注释。[3]
来源: http://tldp.org/LDP/abs/html/sha-bang.html#MAGNUMREF

9

一个脚本的第一行可能会指定 #!/bin/bash,意味着该脚本应始终使用 bash 运行,而不是其他 shell。/bin/sh 是代表系统 shell 的可执行文件。实际上,它通常被实现为符号链接,指向系统 shell 所在的可执行文件。


1

这是 shell 可执行文件所在的路径。


0

它被操作系统用于具有执行位设置的常规文件。如果文件未被识别为“纯”二进制格式(即ELF、DWARF或其他格式),操作系统会尝试读取 #!/path/to/interpreter -plus -options 并转换:

myscript myargument

转换为:

/path/to/interpreter -plus -options myscript myargument

它还会安排argc和argv正确(即,argv [0]将是您的脚本名称,argv [1]是选项1等)。

这对于Perl脚本、Python脚本以及诸如此类的脚本也适用。实际上,适用于您选择的任何解释器。


0

这意味着当直接执行时(即使/bin/sh是bash的别名),你的脚本会以兼容模式(POSIX)运行。


针对那些给出负评的人,以下是引用:

Bourne shell(或称 sh)是 Unix Version 7 的默认 Unix shell,并且大多数类 Unix 系统仍然拥有 /bin/sh - 它将是 Bourne shell,或者是符号链接或硬链接到兼容 shell 的 Bourne shell - 即使在大多数用户使用更现代的 shell 的情况下。

http://en.wikipedia.org/wiki//bin/sh

并且:

使用Bash特定功能(bashisms)编写的Shell脚本将无法在使用Bourne shell或其替代品的系统上运行,除非安装了Bash并且脚本以“shebang line”开头,指定解释器为#!/bin/bash,而不是#!/bin/sh。

http://en.wikipedia.org/wiki/Bash_(Unix_shell)#Portability


这与兼容模式无关。那是Bash的一个功能,并不是#!通用的。 - The Archetypal Paul
你错了,/bin/sh 在符合 POSIX 标准的系统中实际上并不是 Bourne-sh shell,它意味着“任何符合 POSIX 标准的 shell”,并且它是规范的一部分。当你使用它时,你表明你正在编写符合 POSIX 标准的 sh 代码,而不管使用的是哪个 shell,因为在 bash 的情况下,它以兼容模式运行(其他 shell 可能会有不同的行为,但这个 shebang 的唯一保证是你已经并且正在使用 POSIX)。 - Samus_
你提供了两个引用,都没有涉及到POSIX标准。第一个链接只是说当通过#!/bin/sh使用时,Bash变得兼容POSIX。所以我认为你描述的仍然是Bash的特性,并不是任何跟#!/bin/sh一般相关的东西。 - The Archetypal Paul
1
Samus的答案是正确的,但可能不是他或她认为的那样。答案的写法表明/bin/sh是某种神奇的东西,并且会导致内核运行一个兼容bourne shell的程序,而与/bin/sh链接到哪里无关。不是这样的:如果/bin/sh被符号链接到bash,则运行的就是bash,但bash会发现它是在sh的名称下被调用的,并因此以兼容模式运行,在这种模式下,它的行为类似于历史/POSIX sh - Norman Gray
好的,是的,/bin/sh 就像任何其他文件系统元素一样,但这并不意味着它是特定的 shell,特别是不必是 Bourne-sh,它可能是或可能是其他东西(甚至可能不存在),因此您不能假设任何关于它的事情,除了 POSIX-sh 特性,而且只有在 POSIX 兼容环境中才能使用,因为 POSIX 要求如此。 - Samus_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接