Perl如何处理shebang线?

时间:2017-08-29 22:44:51

标签: perl shebang perl5

我试图理解perl如何处理shebang线。

使用认为"命令位置"中提到的任何解释器。在命令行上将优先于shebang行中提到的一个。例如,如果名为demo的可执行脚本看起来像这样

#!/usr/local/bin/perl-5.00503

printf "$]\n";

...然后我会观察以下内容:

$ ./demo
5.00503
% /usr/local/bin/perl-5.22 ./demo
5.022003

IOW,在第一次执行中,shebang中的解释器是正在运行的解释器,而在第二次执行中,它是在命令行中提到的解释器。到目前为止一切都很好。

但是现在,如果我改变"翻译"在shebang上的/usr/bin/wc之类的东西,它总是胜过我在命令行中提到的任何 perl 解释器:

% cat demo-wc
#!/usr/bin/wc

printf "$]\n";

% ./demo-wc                           # produces the expected behavior
       4       3      31 ./demo-wc
% /usr/local/bin/perl-5.22 ./demo-wc
       4       3      31 ./demo-wc
% /usr/local/bin/perl-5.14 ./demo-wc
       4       3      31 ./demo-wc

AFAICT,这种特殊行为似乎是有限的perl口译员;非perl解释员,例如/bin/bash,做"否决" shebang:

% /bin/bash ./demo-wc
$]

最重要的是,perl似乎根据所提到的翻译来处理shebang的政策完全不同。

  1. perl如何确定要遵循的政策?
  2. 两种情况下的政策究竟是什么?

2 个答案:

答案 0 :(得分:6)

您的测试中有几种不同的情况。

当你使用./demo...时,内核在幻数(前16位)中找到#!并运行该程序,或者如果它失败则将该行传递给shell,这将启动它上面的内容

但是当您在命令行上调用perl时,该二进制文件由shell启动,然后perl解释器本身处理shebang。在这种情况下,它会丢弃perl部分,但会考虑开关 - 如果该行包含“perl”。

如果shebang 调用perl,我们对Perl有特殊行为。 来自perlrun

  

如果#!行不包含单词“perl”或单词“indir”,则执行以#!命名的程序而不是Perl解释器。这有点奇怪,但它可以帮助那些没有#!的机器上的人,因为他们可以告诉程序他们的SHELL是 / usr / bin / perl ,然后Perl会将程序发送给正确的解释器。

答案 1 :(得分:2)

与大多数其他解释器不同,perl自己处理#!行。这使它能够采用多个选项参数,即使内核的#!处理程序只传递一个字符串。

详细信息在perlrun手册页中。您的相关部分是:

  

如果是“#!” line不包含单词“perl”,也不包含单词“indir”以“#!”命名的程序执行而不是Perl解释器。这有点奇怪,但它可以帮助那些没有“#!”的机器上的人,因为他们可以告诉程序他们的SHELL是/ usr / bin / perl,然后Perl会将程序发送到正确的解释器它们。