在大多数情况下,客观上是否有比其他人更好的Bash shebang?

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

我依稀记得很久以前听人说过,在结尾加一个破折号会阻止某人向脚本传递命令,但找不到任何细节。


当前回答

/bin/sh通常是系统默认shell的链接,它通常是bash,但在例如Debian系统中使用的是较轻的dash。无论哪种方式,最初的Bourne shell都是sh,因此如果您的脚本使用了一些bash(第二代,“Bourne Again sh”)特定的功能([[]]测试、数组、各种甜蜜的东西等),那么您应该更加具体,并使用后者。这样,在未安装bash的系统上,脚本将无法运行。我知道可能会有一部关于这种进化的激动人心的电影三部曲。。。但这可能是传闻。

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

其他回答

/bin/sh通常是系统默认shell的链接,它通常是bash,但在例如Debian系统中使用的是较轻的dash。无论哪种方式,最初的Bourne shell都是sh,因此如果您的脚本使用了一些bash(第二代,“Bourne Again sh”)特定的功能([[]]测试、数组、各种甜蜜的东西等),那么您应该更加具体,并使用后者。这样,在未安装bash的系统上,脚本将无法运行。我知道可能会有一部关于这种进化的激动人心的电影三部曲。。。但这可能是传闻。

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

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

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

你应该使用#/usr/bin/env bash可移植性:不同的*nixes将bash放在不同的位置,使用/usr/bin/env是运行PATH上找到的第一个bash的变通方法。sh不是bash。

使用shebang行调用适当的解释器不仅仅适用于BASH。您可以将shebang用于系统上的任何解释语言,如Perl、Python、PHP(CLI)等。顺便说一下,shebang

#!/bin/sh -

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

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

#!/usr/bin/env bash

或用于任何语言,如Perl

#!/usr/bin/env perl

请务必查看bash的手册页:

man bash

和env:

man env

注意:在Debian和基于Debian的系统上,如Ubuntu,sh链接到dash而不是bash。Debian表示,由于所有系统脚本都使用sh.这允许bash增长,系统保持稳定。

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

我建议使用:

#!/bin/bash

它不是100%可移植的(有些系统将bash放在/bin以外的位置),但事实上,许多现有脚本都使用#/bin/bash迫使各种操作系统使/bin/bash至少成为到主位置的符号链接。

替代方案:

#!/usr/bin/env bash

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

(但是/usr/bin/env应该适用于任何合理的现代系统,因为env在/usr/bin中,或者因为系统做了一些事情使其工作。我上面提到的系统是SunOS4,我可能已经25年没有使用过了。)

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

在回答这个问题时,我已经更深入地讨论了权衡。

一个有点晦涩的更新:我使用的一个系统,Termux,一个在Android下运行的类似Linux的桌面层,没有/bin/bash(bash是/data/data/com.Termux/files/usr/bin/bash)——但它有特殊的处理来支持#/bin/bash。