【发布时间】:2011-11-28 08:37:51
【问题描述】:
显然这同样适用于用 python、bash、sh 等代替 perl!
昆汀在下面的回答显然是正确的,所以我接受了它,但我想我的真正意思是“使用 #! 的两种方式的优缺点是什么!调用 perl/python/bash 作为脚本的解释器?'
【问题讨论】:
-
这个问题与特定的脚本语言没有任何关系,但我将其标记为 perl,因为这是标题中使用的示例。
显然这同样适用于用 python、bash、sh 等代替 perl!
昆汀在下面的回答显然是正确的,所以我接受了它,但我想我的真正意思是“使用 #! 的两种方式的优缺点是什么!调用 perl/python/bash 作为脚本的解释器?'
【问题讨论】:
其中一个引用了安装 perl 的常见位置。另一个引用了一个安装 env 的公共位置,并询问它默认 perl 的路径是什么。
【讨论】:
这些都是很好的规则,如果你有充分的理由打破它们,不要犹豫:
尽可能使用#!/usr/bin/env perl 以实现异构系统之间的可移植性。但这是一种愚蠢的做法,因为它假设路径中的第一个 Perl 也是您一直想要的 Perl。情况可能并非如此,而且通常当系统上有多个 Perls 时,它们的存在是出于某种原因。
更好的方法是将脚本打包到 CPAN 就绪的发行版中。将发行版分发到您想要安装它们的系统,并以通常的方式(手动或使用 CPAN 工具链)安装它们,指定完整路径到perl 或cpan。在此过程中,the shebang line is rewritten 指向 Perl 的正确路径。
例子:
tar -xvf Local-OurCompany-Scripts-1.000.tar.gz
cd Local-OurCompany-Scripts-1.000
## automated installation
/usr/bin/cpan .
# or perhaps
/opt/ourcompany/perls/perl-5.14.2/bin/cpan .
## manual installation
/usr/bin/perl Makefile.PL ; make ; make install
# or perhaps
`which perl5.14.2` Makefile.PL ; make ; make install
【讨论】:
env 允许您为不同的程序使用不同的 perls(甚至在不同的时间使用相同的程序)。使用硬编码的 perl 路径和 CPAN 的路径重写功能会假设用于进行安装的 perl 是您一直想要的 perl,我认为这是一个比 env 所做的更大(更糟糕)的假设,因为它需要修改源以覆盖它,而不是简单的“PATH=/path/to/other/perl:$PATH some_perl.pl”。
使用env 来查找可执行文件,而不是自己查找,会执行额外的执行,但大多数时候这并不重要。很方便,我自己也经常用。
但是,有人在系统脚本中使用 env 时遇到了问题。 On one occasion,安装 /usr/local/bin/perl 破坏了我的系统,因此在解决问题之前我无法再更新它。 On another occasion,安装 /usr/local/bin/python 破坏了我正在使用的 ID3 标记器。我认为这更像是一个包装问题,而不是env 的固有问题。如果您要在系统上安装某些东西,那么为什么要仔细检查它是否具有满足所有依赖项的 Python 版本,如果您只是要留下一条每次都在寻找任何旧版本 Python 的 shebang 行运行了吗?
【讨论】:
env 没有理由分叉另一个进程。您是指“高管”,还是介意扩展该主题?
我可以给你一个具体的例子:
假设您在 /opt/(即 XAMPP)中安装了一个 LAMP 包,其中包括它自己的 perl 可执行文件、库和包管理器。
您实际上想要运行该可执行文件,因此您在 PATH 环境变量 (PATH="/opt/XAMPP/bin:$PATH") 中添加 LAMP 可执行文件的路径。
现在任何使用“#!/usr/bin/env perl”的脚本都将执行 LAMP 堆栈目录中的 perl 二进制文件。另一个路径将执行系统中预安装的 perl 二进制文件,在“/usr/bin/perl”中。
由您决定什么对您的 perl 脚本更好。
【讨论】: