What is the preferred Bash shebang?
在大多数情况下,是否有比其他人更客观地更好的Bashshebang?
- #!/usr/bin/env bash
- #!/bin/bash
- #!/bin/sh
- #!/bin/sh -
- 等
我隐约记得很久以前听说在结尾添加破折号会阻止某人向脚本传递命令,但找不到任何细节。
- 以及OpenBSD上的/usr/local/bin/bash。
你应该使用#!/usr/bin/env bash作为可移植性:不同的尼克斯把bash放在不同的地方,而使用/usr/bin/env是运行PATH上发现的第一个bash的变通方法。而sh不是bash。
- 谢谢。也像是在增加-到$的末尾!/usr/bin/env bash—不会做任何事情,因为shebang中的*nix只允许一个参数,而"bash"使用这个参数。如果脚本的shebang是其他没有参数的脚本之一(/bin/sh等),那么这显然只对防止恶意参数传递到命令行上的脚本有用。
- 为什么不是#!/bin/bash?这是否取决于用户是否定义了正确的path?
- @Raybash并不存在于所有系统上的/bin中。
- ^^ Windows Git bash路径是/user/bin/bash,但我的Siteground宿主路径是/bin/bash(与echo $SHELL一起检查)。
- 对我来说也是一样,我只是把它添加到了一个别名:alias shebang='echo"#!/usr/bin/env bash"',现在我只需要打开终端,输入shebang就可以了,而不必到这里。
- sh是什么语言?
- hey@kolobcanyon"bash基本上是sh,具有更多的特性和更好的语法"(参见askubuntu.com/a/141932)
- 这个答案是有欺骗性的。posix没有说env在/usr/bin/env处。它可能在/bin/env或实际上在任何地方,只要它在道路上。如果/dummy在path中,则可能在/dummy/env处。shebang本身在posix下是未定义的,所以我可以让#!stop toaster启动usb咖啡机,使之符合posix。因此,#!/usr/bin/env bash并没有比#!/bin/bash更好,它可能不太便于携带。
- @Darkfeline的可移植性并不是绝对的——在数学上不可能让任何脚本在每个平台上执行相同的操作。截至2012年至2018年,/usr/bin/env在多台机器上的存在超过了/bin/bashxor /usr/bin/bash,因此以此行开头的脚本将在尽可能多的机器上完成预期的工作。
- @i0b0如果我的路径中有正确的版本,它将完成预期的事情。我不能指定我的脚本需要使用shebang的bash4.2或更高版本;我只能记录该需求。真的,脚本编写者不应该是控制shebang的人;应该是运行脚本的人。python做得很好,imo:脚本使用#!python,安装程序将其替换为目标系统的正确shebang。
- @实际上,在posix下可移植性是绝对的。当然,假设bash在路径中,您可以使用这样的脚本。没有shebang和不匹配二进制可执行格式的可执行文件使用sh运行。这在posix下是完全可移植的,与此答案不同。(不好意思进行双重评论,StackOverflow评论编辑太蠢了。)
- 这对Windows(Git-Bash、Cygwin)有效吗?
/bin/sh通常是指向系统默认shell的链接,后者通常是bash,但在上,例如,debian系统是重量较轻的dash。不管怎样,最初的bourne shell是sh,所以如果脚本使用了一些bash(第二代,"bourne again sh")特定的特性([[ ]]测试、数组、各种糖类等),那么您应该更具体一些,以后再使用。这样,在没有安装bash的系统上,脚本就不会运行。我知道可能会有一部关于这种进化的激动人心的三部曲电影……但那可能是道听途说。
另请注意,当作为sh调用时,bash在某种程度上表现为posix标准sh(另请参见GNU文档)。
- 公共域korn shell(pdksh)是openbsd上的默认值。
- "在我的手开始颤抖之前,我可以在半英里内打字。"
- 大多数系统不会将/bin/sh链接到/usr中的任何地方,因为这会使in it脚本在安装/usr之前很难运行。
- @aij我不知道为什么我会把"很多或大多数"放在那里——我是一个Fedora用户,在这里,/bin和/sbin多年来一直是默认的符号链接,到/usr/bin和/usr/sbin,因此在这种情况下,/bin/sh是到bash的链接,实际目录是/usr/bin。但我会纠正上面的错误。
使用shebang行调用适当的解释器不仅仅是为了bash。您可以将shebang用于系统上的任何解释语言,如perl、python、php(cli)和许多其他语言。顺便说一下,舍邦
(也可以是两个破折号,即--结束bash选项之后的所有内容都将被视为文件名和参数。
使用env命令使脚本可移植,并允许您为脚本设置自定义环境,因此应使用可移植脚本
或者是任何语言,比如Perl
务必查看bash的man页:
和env:
注:在基于Debian和Debian的系统上,如Ubuntu,sh与dash相连,而不是与bash相连。因为所有系统脚本都使用sh。根据Debian的说法,这允许bash增长,系统保持稳定。
另外,为了保持调用*nix,我从来没有在shebang调用的脚本上使用文件扩展名,因为您不能像在Windows上那样忽略可执行文件调用的扩展名。文件命令可以将其标识为脚本。
我建议使用:
它不是100%可移植的(有些系统将bash放在/bin以外的位置),但事实上,许多现有的脚本使用#!/bin/bash对各种操作系统施加压力,使/bin/bash至少与主位置形成符号链接。
备选方案:
有人建议——但不能保证env命令在/usr/bin中(我在没有的地方使用过系统)。此外,此表单将在当前用户$PATH中使用bash的第一个实例,这可能不是bash shell的合适版本。
如果需要在没有/bin/bash的系统上运行脚本,可以修改脚本以指向正确的位置(这显然不方便)。
在我对这个问题的回答中,我更深入地讨论了权衡。
这实际上取决于您如何编写bash脚本。如果您的/bin/sh与bash符号链接,当bash作为sh调用时,某些功能将不可用。
如果您想要bash特定的、非posix特性,请使用#!/bin/bash。
- OpenBSD上没有安装bash。如果您通过pkg_add安装它,那么它位于/usr/local/bin中,可能不在路径上。