什么是首选的Bash shebang?

Kur*_*sis 1051 bash shebang

有没有什么Bash家当客观上比其他大多数应用更好?

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

我很清楚地回忆起很久以前的一次听说,在最后添加一个破折号可以防止有人将命令传递给你的脚本,但却无法找到任何细节.

l0b*_*0b0 1425

您应该使用#!/usr/bin/env bash便携性:不同的*nixes放在bash不同的地方,并使用/usr/bin/env是运行第一种解决方法bash上找到PATH.而sh不是bash.

  • 这个答案具有欺骗性.POSIX没有说'env`在`/ usr/bin/env`.它可以在`/ bin/env`或其他任何地方,只要它在路径中.如果`/ dummy`在`PATH`中,它可能在`/ dummy/env`.Shebang本身在POSIX下是未定义的,所以我可以让`#!stop toaster`启动USB咖啡机并且符合POSIX标准.所以`#!/ usr/bin/env bash`并不比`#!/ bin/bash`特别好,它可能不那么便携了. (16认同)
  • @darkfeline可移植性并不是绝对的 - 在数学上不可能制作任何在每个平台上都能做同样事情的脚本.从2012年到2018年,`/ usr/bin/env`存在于比`/ bin/bash` xor`/usr/bin/bash`更多的机器上,所以以这行开头的脚本将*执行预期的事情在尽可能多的机器上.* (14认同)
  • @Ray`bash`并不存在于所有系统的`/ bin`中. (13认同)
  • 我也一样,我只是把它添加到一个别名:"'!#在/ usr/bin中/ env的庆典’回声"`别名家当=',现在我只需要打开终端输入家当,而不是去这里. (11认同)
  • 谢谢.也看起来像添加 - 到$!/ usr/bin/env bash的结尾 - 不会做任何事情,因为shebang中的*nix只允许一个参数,而'bash'使用它.如果脚本的shebang是没有参数的其他人之一(`/ bin/sh`等),这显然只对防止恶意参数传递到命令行上的脚本有用. (9认同)
  • 为什么不`#!/ bin/bash`?这取决于用户是否定义了正确的`path`? (5认同)
  • @ l0b0实际上,在POSIX下可移植性是绝对的。当然,假设Bash在路径中,您可以使用[this](https://gist.github.com/darkfeline/19a91aa9e59259bb61e4614a32091600)这样的脚本。使用she运行没有shebang并且不匹配二进制可执行格式的可执行文件。与这个答案不同,它在POSIX下是完全可移植的。(对不起,有重复评论,愚蠢的StackOverflow评论编辑。) (2认同)
  • @bgibson 有趣的问题,但是不行,第一个命令必须是绝对路径。否则我们就不需要这个解决方法,并且 shebang 行可能只是“#!bash”。 (2认同)

del*_*ver 78

/bin/sh通常是系统默认shell的链接,这通常是bash打开的,例如,Debian系统的重量较轻dash.无论哪种方式,最初的Bourne shell都是sh,所以如果你的脚本使用了一些bash(第2代,"Bourne Again sh")特定的功能([[ ]]测试,数组,各种含糖的东西等),那么你应该更具体并使用更晚的.这样,在未安装bash的系统上,您的脚本将无法运行.我知道可能有一部关于这种演变的令人兴奋的电影三部曲...但这可能是传闻.

还要注意,当被唤起时sh,bash在某种程度上表现为POSIX标准 sh(另请参阅关于此的GNU文档).

  • Public Domain Korn Shell(pdksh)是OpenBSD的默认设置. (2认同)
  • 大多数系统不会将“/bin/sh”链接到“/usr”中的任何位置,因为这会使初始化脚本在安装“/usr”之前很难运行。 (2认同)

小智 22

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

#!/bin/sh -
Run Code Online (Sandbox Code Playgroud)

(它也可以是两个破折号,即--)结束bash选项后将被视为文件名和参数.

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

#!/usr/bin/env bash
Run Code Online (Sandbox Code Playgroud)

或者对于Perl这样的语言

#!/usr/bin/env perl
Run Code Online (Sandbox Code Playgroud)

请务必查看以下man页面bash:

man bash
Run Code Online (Sandbox Code Playgroud)

并且env:

man env
Run Code Online (Sandbox Code Playgroud)

注意:在Debian和基于Debian的系统上,如Ubuntu,sh与之dash无关bash.所有系统脚本都使用sh.根据Debian的说法,这可以让bash成长并使系统保持稳定.

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


Kei*_*son 22

我建议使用:

#!/bin/bash
Run Code Online (Sandbox Code Playgroud)

它不是100%可移植的(一些系统bash位于除了之外的位置/bin),但是许多现有脚本使用#!/bin/bash压力使各种操作系统/bin/bash至少对主要位置进行符号链接这一事实.

替代方案:

#!/usr/bin/env bash
Run Code Online (Sandbox Code Playgroud)

有人建议 - 但不能保证env命令在/usr/bin(并且我使用的系统不是).此外,此表单将使用bash当前用户的第一个实例$PATH,这可能不是bash shell的合适版本.

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

这个问题的回答中,我已经更深入地讨论了权衡.

  • 两年后,这仍然是最好的建议。如果简单的解决方案不起作用,那么您就必须质疑您之前的决定。被接受和最多支持的答案并没有错,只是不正确:) (6认同)

gle*_*man 5

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

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

  • Bash 没有安装在 OpenBSD 上。如果您通过`pkg_add` 安装它,那么它位于`/usr/local/bin`,它可能不在路径上。 (3认同)