简体   繁体   English

首选 Bash shebang(“#?”)是什么?

[英]What is the preferred Bash shebang ("#!")?

Is there any Bash shebang objectively better than the others for most uses?对于大多数用途,是否有任何Bash shebang 客观上比其他更好?

  • #!/usr/bin/env bash
  • #!/bin/bash
  • #!/bin/sh
  • #!/bin/sh -
  • etc ETC

I vaguely recall a long time ago hearing that adding a dash to the end prevents someone passing a command to your script, but can't find any details on that.我依稀记得很久以前听说在末尾添加破折号可以防止有人向您的脚本传递命令,但找不到任何详细信息。

You should use #!/usr/bin/env bash for portability : different *nixes put bash in different places, and using /usr/bin/env is a workaround to run the first bash found on the PATH .您应该使用#!/usr/bin/env bash以实现可移植性:不同的 *nixes 将bash放在不同的位置,使用/usr/bin/env是运行在PATH上找到的第一个bash的解决方法。 And sh is not bash .而且sh不是bash

I recommend using:我建议使用:

#!/bin/bash

It's not 100% portable (some systems place bash in a location other than /bin ), but the fact that a lot of existing scripts use #!/bin/bash pressures various operating systems to make /bin/bash at least a symlink to the main location.它不是 100% 可移植的(某些系统将bash放置在/bin以外的位置),但是许多现有脚本使用#!/bin/bash的事实迫使各种操作系统使/bin/bash至少成为指向主要位置。

The alternative of:替代方案:

#!/usr/bin/env bash

has been suggested -- but there's no guarantee that the env command is in /usr/bin (and I've used systems where it isn't).已被建议 - 但不能保证env命令在/usr/bin (我已经使用了它不在的系统)。 Furthermore, this form will use the first instance of bash in the current users $PATH , which might not be a suitable version of the bash shell.此外,此表单将使用当前用户$PATH的第一个bash实例,这可能不是 bash shell 的合适版本。

(But /usr/bin/env should work on any reasonably modern system, either because env is in /usr/bin or because the system does something to make it work. The system I referred to above was SunOS 4, which I probably haven't used in about 25 years.) (但是/usr/bin/env应该可以在任何合理的现代系统上运行,要么是因为env/usr/bin ,要么是因为系统做了一些事情来使它工作。我上面提到的系统是 SunOS 4,我可能没有大约 25 年未使用。)

If you need a script to run on a system that doesn't have /bin/bash , you can modify the script to point to the correct location (that's admittedly inconvenient).如果您需要一个脚本在没有/bin/bash的系统上运行,您可以修改脚本以指向正确的位置(这无疑是不方便的)。

I've discussed the tradeoffs in greater depth in my answer to this question .我在回答这个问题时更深入地讨论了权衡。

A somewhat obscure update: One system I use, Termux , a desktop-Linux-like layer that runs under Android, doesn't have /bin/bash ( bash is /data/data/com.termux/files/usr/bin/bash ) -- but it has special handling to support #!/bin/bash .一个有点模糊的更新:我使用的一个系统, Termux ,一个在 Android 下运行的类似桌面 Linux 的层,没有/bin/bashbash/data/data/com.termux/files/usr/bin/bash ) - 但它有特殊的处理来支持#!/bin/bash

/bin/sh is usually a link to the system's default shell, which is often bash but on, eg, Debian systems is the lighter weight dash . /bin/sh通常是指向系统默认 shell 的链接,它通常是bash但在例如 Debian 系统上是较轻的dash Either way, the original Bourne shell is sh , so if your script uses some bash (2nd generation, "Bourne Again sh") specific features ( [[ ]] tests, arrays, various sugary things, etc.), then you should be more specific and use the later.无论哪种方式,原始的 Bourne shell 都是sh ,所以如果您的脚本使用了一些bash (第二代,“Bourne Again sh”)特定功能( [[ ]]测试、数组、各种含糖的东西等),那么您应该更具体,稍后使用。 This way, on systems where bash is not installed, your script won't run.这样,在未安装 bash 的系统上,您的脚本将不会运行。 I understand there may be an exciting trilogy of films about this evolution...but that could be hearsay.我知道可能会有一部关于这种演变的令人兴奋的电影三部曲……但这可能是道听途说。

Also note that when evoked as sh , bash to some extent behaves as POSIX standard sh (see also the GNU docs about this).另请注意,当作为shbash在某种程度上表现为 POSIX 标准sh (另请参阅关于此的 GNU 文档)。

Using a shebang line to invoke the appropriate interpreter is not just for BASH.使用 shebang 行调用适当的解释器不仅适用于 BASH。 You can use the shebang for any interpreted language on your system such as Perl, Python, PHP (CLI) and many others.您可以将 shebang 用于系统上的任何解释性语言,例如 Perl、Python、PHP (CLI) 和许多其他语言。 By the way, the shebang顺便说一句,shebang

#!/bin/sh -

(it can also be two dashes, ie -- ) ends bash options everything after will be treated as filenames and arguments. (它也可以是两个破折号,即-- )结束 bash 选项之后的所有内容都将被视为文件名和参数。

Using the env command makes your script portable and allows you to setup custom environments for your script hence portable scripts should use使用env命令使您的脚本可移植,并允许您为脚本设置自定义环境,因此可移植脚本应使用

#!/usr/bin/env bash

Or for whatever the language such as for Perl或者任何语言,例如 Perl

#!/usr/bin/env perl

Be sure to look at the man pages for bash :请务必查看bashman页:

man bash

and env :env

man env

Note: On Debian and Debian-based systems, like Ubuntu, sh is linked to dash not bash .注意:在 Debian 和基于 Debian 的系统上,如 Ubuntu, sh链接到dash而不是bash As all system scripts use sh .由于所有系统脚本都使用sh This allows bash to grow and the system to stay stable, according to Debian.根据 Debian 的说法,这允许 bash 增长并使系统保持稳定。

Also, to keep invocation *nix like I never use file extensions on shebang invoked scripts, as you cannot omit the extension on invocation on executables as you can on Windows.此外,为了保持调用 *nix 就像我从来没有在 shebang 调用的脚本上使用文件扩展名一样,因为您不能像在 Windows 上那样省略可执行文件的调用扩展名。 The file command can identify it as a script. file 命令可以将其识别为脚本。

It really depends on how you write your bash scripts.这实际上取决于您如何编写 bash 脚本。 If your /bin/sh is symlinked to bash, when bash is invoked as sh , some features are unavailable .如果您的/bin/sh符号链接到 bash,当 bash 作为sh调用时, 某些功能将不可用

If you want bash-specific, non-POSIX features, use #!/bin/bash如果您想要特定于 bash 的非 POSIX 功能,请使用#!/bin/bash

Add one more vote to the #./usr/bin/env approach, I use virtual environments a lot.给#./usr/bin/env 方法再投一票,我经常使用虚拟环境。 in my case I use the python installed in the virtualenv.在我的情况下,我使用安装在 virtualenv 中的 python。 Using #./usr/bin/python may not be the python I want.使用 #./usr/bin/python 可能不是我想要的 python。 I get the right python using #!/usr/bin/env python.我使用 #!/usr/bin/env python 得到了正确的 python。

#!/bin/sh

as most scripts do not need specific bash feature and should be written for sh.因为大多数脚本不需要特定的 bash 功能,应该为 sh 编写。

Also, this makes scripts work on the BSDs, which do not have bash per default.此外,这使得脚本可以在默认情况下没有 bash 的 BSD 上运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM