Bash脚本:#!/bin/bash是什么意思?

155
在Bash脚本中,第一行的#!/bin/bash是指定脚本需要运行的解释器为Bash。如果使用#!/bin/sh则默认使用系统shell作为脚本解释器。
3个回答

196
这被称为shebang,它告诉shell在执行时使用哪个程序来解释脚本。
在您的示例中,该脚本将由bash shell解释和运行。
一些其他示例的shebang包括:
(来自维基百科)
#!/bin/sh — Execute the file using sh, the Bourne shell, or a compatible shell
#!/bin/csh — Execute the file using csh, the C shell, or a compatible shell
#!/usr/bin/perl -T — Execute using Perl with the option for taint checks
#!/usr/bin/php — Execute the file using the PHP command line interpreter
#!/usr/bin/python -O — Execute using Python with optimizations to code
#!/usr/bin/ruby — Execute using Ruby

"我能想到的还有一些额外的,例如:"
#!/bin/ksh
#!/bin/awk
#!/bin/expect

在具有bash shebang的脚本中,例如,您将使用bash语法编写代码;而在具有expect shebang的脚本中,您将使用expect语法编写代码,以此类推。
针对更新部分的回答:
这取决于您系统上的/bin/sh实际指向什么。通常它只是一个指向/bin/bash的符号链接。有时会编写可移植脚本,并使用#!/bin/sh来表示它是一个shell脚本,但它使用特定系统上由/bin/sh引用的任何shell(可能指向/bin/bash、/bin/ksh或/bin/zsh)。

3
谢谢!但是 #!/bin/bash#!/bin/sh 之间有什么区别吗? - Raptor
7
@ShivanRaptor #!/bin/bash 表示在 bash 中运行此脚本。#!/bin/sh 表示在 sh 中运行此脚本,它是默认的 Unix shell,可能是 bash 或其他变体,如 ksh、dash、zsh 等。 - Karthik T
你的第一句话:“这被称为shebang,它告诉shell在执行时用什么程序来解释脚本。”略有错误。它并不是告诉_shell_要执行哪个程序,而是告诉_kernel_要执行哪个程序。此外,任何可执行文件都可以在#!中使用。你可以尝试#!/usr/bin/firefox,甚至如果你有一个位于路径/path/to/script的脚本myscript,那么#!/path/to/script/myscript也可以工作。在这种情况下,myscript将与shebang行中给出的参数一起启动,并且还会包括启动它的文件的文件名。 - gniourf_gniourf
1
哦,哇,那真的很棒,谢谢 @gniourf_gniourf! - sampson-chen
如果它没有被包含在内呢?会选择一些默认值还是脚本会出错? - runnerpaul
显示剩余5条评论

20
在bash脚本中,第一行的#!/bin/bash是什么意思?
在Linux系统中,我们有一个解释我们UNIX命令的shell。现在Unix系统中有许多shell。其中有一个称为bash的shell,它非常常见于Linux,并且有着悠久的历史。这是Linux默认的shell。
当您编写脚本(包含unix命令等)时,您可以选择指定使用哪个shell。通常,您可以使用Shebang(是的,这就是它的名称)来指定使用哪个shell。
因此,如果您在脚本顶部使用#!/bin/bash,则表示您要告诉系统使用bash作为默认shell。
现在来回答您的第二个问题:#!/bin/bash和#!/bin/sh之间有区别吗?
答案是肯定的。当您告诉#!/bin/bash时,您正在告诉您的环境/操作系统使用bash作为命令解释器。这是硬编码的东西。
每个系统都有自己的shell,系统将使用该shell来执行其自己的系统脚本。这个系统shell可能因OS而异(大多数情况下它将是bash。Ubuntu最近使用dash作为默认系统shell)。当您指定#!/bin/sh时,系统将使用其内部系统shell来解释您的shell脚本。
访问link以获取更多信息,我已经在那里解释了这个主题。
希望这可以消除您的困惑...祝你好运。

16
当脚本中的第一个字符为#!时,这被称为shebang。如果您的文件以#!/path/to/something开头,则标准是运行something并将文件的其余部分作为输入传递给该程序。
话虽如此,#!/bin/bash#!/bin/sh甚至#!/bin/zsh之间的区别在于使用bash、sh或zsh程序来解释文件的其余部分。bashsh只是不同的程序,传统上而言,在某些Linux系统上,它们是相同程序的两个副本。在其他Linux系统上,sh是指向dash的链接,在传统的Unix系统(Solaris,Irix等)上,bash通常是与sh完全不同的程序。
当然,该行剩余部分不必以 "sh" 结尾。它也可以是 #!/usr/bin/python, #!/usr/bin/perl, 或者甚至是 #!/usr/local/bin/my_own_scripting_language

“sh”通常是在兼容模式下运行的“bash”,自从bash成为大多数Linux发行版的默认shell以来,这一点就一直如此,而且我IRC还有好几年,可以肯定已经有15年了,可能超过20年。 - ocodo
在我的Debian和Ubuntu系统中,/bin/sh是dash。Android表示它使用ash作为/bin/sh。 - Joshua D. Boyd
1
@JoshuaDBoyd 很好的发现,许多(虽然可能不是全部)BSD Unix 使用 Ash 作为默认 shell,而不是 Bash,Debian / Ubuntu 使用 Dash。同样,Ash 和 Dash 都有 sh 兼容模式。如果我们深入研究 Solaris、Aix、HPUX、Ultrix、SCO 等系统,每个系统都会有自己的默认 shell,并且会有 sh 模拟(以保持 POSIX 兼容性)。 - ocodo

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