首选的Bash shebang是什么?


1127

Bash在大多数情况下,有没有一种射手在客观上要优于其他射手?

  • #!/usr/bin/env bash
  • #!/bin/bash
  • #!/bin/sh
  • #!/bin/sh -
  • 等等

我隐约记得很久以前,听说在末尾添加破折号会阻止某人向您的脚本传递命令,但找不到任何详细信息。


4
及其/usr/local/bin/bash在OpenBSD上。
jww

Answers:


1531

您应该使用它#!/usr/bin/env bash来实现可移植性:将不同的* nix放在bash不同的位置,并使用/usr/bin/env一种解决方法来运行在上bash找到的第一个PATH。而且sh不是bash


9
谢谢。看起来也像添加-在$!/ usr / bin / env bash的末尾-不会做任何事情,因为sheni中的* nix只允许一个参数,而'bash'使用了它。如果脚本的shebang是不带参数的其他脚本之一(/bin/sh,等等),那么这显然仅对防止恶意参数在命令行上传递给脚本有用。
Kurtosis

13
@Ray bash并非存在于/bin所有系统中。
ptierno 2014年

12
对我来说也一样,我只是将其添加到别名:中alias shebang='echo "#!/usr/bin/env bash"',现在只需要打开终端并输入shebang即可,而不是去这里。
Oylex

19
这个答案是骗人的。POSIX并没有说env/usr/bin/env/bin/env实际上,它可以在路径中,也可以在任何地方。这可能是在/dummy/env如果/dummyPATH。Shebang本身在POSIX下是未定义的,因此我可以#!stop toaster启动USB咖啡机并兼容POSIX。因此,它#!/usr/bin/env bash并不是特别好#!/bin/bash,取决于它的可移植性。
darkfeline

19
@darkfeline可移植性不是绝对的-从数学上讲,不可能使任何脚本在每个平台上都可以做同样的事情。从2012年到2018年/usr/bin/env,与/bin/bashxor相比/usr/bin/bash,存在的计算机数量更多,因此以该行开头的脚本将在尽可能多的计算机上完成预期的工作。
l0b0

80

/bin/sh通常是到系统默认Shell的链接,bash但通常在Debian系统上使用,但重量较轻dash。无论哪种方式,原始的Bourne shell都是sh,因此,如果您的脚本使用某些bash(第二代,“ Bourne Again sh”)特定功能([[ ]]测试,数组,各种含糖的东西等),那么您应该更加具体,并使用后面的。这样,在未安装bash的系统上,脚本将无法运行。我了解电影可能会涉及到这种演变的令人兴奋的三部曲……但这可能是传闻。

还要注意,当被调用为时shbash在某种程度上表现为POSIX标准 sh(另请参见GNU文档)。


2
OpenBSD上默认使用Public Domain Korn Shell(pdksh)。
jww

大多数系统都不会链接/bin/sh到任何位置,/usr因为这将导致在/usr挂载之前很难运行init脚本。
aij

@aij我不知道为什么我把“许多或多数”有-我是Fedora用户,其中/bin/sbin多年刚被默认情况下符号链接,以/usr/bin/usr/sbin,所以在这方面/bin/sh是一个链接bash和实际目录是/usr/bin。但我会纠正上述问题。
精致的

43

我建议使用:

#!/bin/bash

它不是100%可移植的(某些系统放置bash在以外的位置/bin),但是许多现有脚本使用#!/bin/bash压力迫使各种操作系统/bin/bash至少与主位置建立符号链接。

替代方案:

#!/usr/bin/env bash

已经提出了建议-但不能保证env命令已在其中/usr/bin(并且我使用的系统不在其中)。此外,此表单将使用bash当前用户中的第一个实例$PATH,它可能不是bash shell的合适版本。

(但是/usr/bin/env应该在任何合理的现代系统上都可以使用,无论env/usr/bin因为内置的系统还是因为该系统能够使它正常工作。我上面提到的系统是SunOS 4,我大概已经有25年没有使用它了。)

如果您需要脚本在没有的系统上运行,则/bin/bash可以修改脚本以指向正确的位置(这很不方便)。

我在讨论更深入的权衡我的回答这个问题

一个有点模糊的更新:我使用的一个系统Termux是在Linux下运行的类似于Linux的桌面层,它没有/bin/bashbashis /data/data/com.termux/files/usr/bin/bash),但是需要特殊处理#!/bin/bash


3
两年后,这仍然是这里的最佳建议。如果简单的解决方案不起作用,那么您必须质疑您先前的决定。公认且最受好评的答案没有错,这是不对的:)
软件工程师,

26

使用shebang行来调用适当的解释器不仅限于BASH。您可以将shebang用于系统上的任何解释语言,例如Perl,Python,PHP(CLI)以及许多其他语言。顺便说一句

#!/bin/sh -

(也可以是两个破折号,即--)结尾bash选项,之后的所有内容都将被视为文件名和参数。

使用该env命令可使脚本可移植,并允许您为脚本设置自定义环境,因此可移植脚本应使用

#!/usr/bin/env bash

或任何语言,例如Perl

#!/usr/bin/env perl

确保查看以下man页面bash

man bash

env

man env

注意:在Debian和基于Debian的系统上,例如Ubuntu,sh链接到dashnot bash。由于所有系统脚本都使用sh。根据Debian的说法,这可以使bash增长并使系统保持稳定。

另外,为了保持调用* nix的效果,就像我从不在shebang调用的脚本上使用文件扩展名一样,因为您不能像在Windows上那样忽略可执行文件的调用扩展名。file命令可以将其标识为脚本。


4

这实际上取决于您如何编写bash脚本。如果将您/bin/sh的符号链接到bash,则以 bash身份调用时sh某些功能将不可用

如果您想要特定于bash的非POSIX功能,请使用 #!/bin/bash


3
Bash未安装在OpenBSD上。如果您通过安装它pkg_add,则其位于中/usr/local/bin,可能不在路径上。
jww

POSIX功能如何?
Nikolan Asad
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.