shebang中哪种类型的路径更可取?

Rom*_*nov 22 scripts shebang

在脚本中,第一行应该指定解释器的路径。
但是在 Linux、Unix 或 BSD 的不同服务器上,此路径可能不同。

什么更可取?

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

或者

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

Kei*_*son 23

如果要使用安装在标准位置的给定解释器的系统安装版本,请使用直接路径。如果您想使用在用户的 中首先出现的任何版本的解释器$PATH,请使用#!/usr/bin/env ....

env命令调用指定的命令,让您设置或取消设置环境变量:

env FOO=BAR do-something
env DISPLAY=:0.0 xterm -ls &
Run Code Online (Sandbox Code Playgroud)

如果您不指定任何环境变量或其他选项,它只会调用命名命令。(以这种方式使用它可以说是有点黑客。)

写shebang的目的是

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

是调用一切interp首先出现$PATH

这意味着你不必知道,写剧本的时候,正是interp为(比方说,如果它的形式可以是/bin/usr/bin/usr/local/bin)。当然,您确实必须知道它env/usr/bin/env,但这似乎是相当普遍的。

优点是它会调用首先出现在用户$PATH. 的缺点是,它调用哪个解释的第一个版本出现在用户的$PATH

例如,假设我已经perl在我的主目录下安装了个人版本as $HOME/bin/perl,并且$HOME/bin在我的$PATH. 如果我运行一个脚本,其shebang是

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

然后它将使用我自己安装的perl可执行文件运行——这可能不是一件好事。该脚本的作者可能还没有使用我一个月前从源代码构建的前沿 Perl 对其进行测试。

对于像 Perl 或 Bash 这样可能安装在大多数系统(/usr/bin/perl/bin/bash分别)上一致位置的东西,我会使用命令的直接路径。对于可以在不同系统上以不同方式安装的更晦涩的东西,我要么使用/usr/bin/env技巧,要么编写一个安装程序,在安装脚本时调整 shebang 行。(我曾经必须为我的 Perl 脚本这样做。)

更新:我在Unix & Linux 站点上对这个问题的回答中更详细地介绍了一点


小智 6

最佳做法是这样的:

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

等等...

当 Ubuntu 首次开始使用 dash 时,一些脚本出现了问题。有关于它的讨论。大多数脚本都是#!/bin/sh通过指向 /bin/bash 的链接编写的。共识是:脚本编写者负责指定解释器。因此,如果您的脚本应始终使用 BASH 调用,请从环境中指定它。这使您不必猜测路径,这在各种 Unix/Linux 系统上是不同的。此外,如果明天 /bin/sh 成为指向其他 shell 的链接(如 /bin/wthsh 或其他一些废话),它将起作用。