在大多数情况下,客观上是否有比其他人更好的Bash shebang?
#!/usr/bin/env bash#!/bin/bash#!/bin/sh#!/bin/sh-等
我依稀记得很久以前听人说过,在结尾加一个破折号会阻止某人向脚本传递命令,但找不到任何细节。
在大多数情况下,客观上是否有比其他人更好的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。