Perl如何处理shebang线?

kjo*_*kjo 2 perl shebang perl5

我正在努力了解如何perl处理shebang线.

曾经认为命令行中"命令位置"中提到的任何解释器都优先于shebang行中提到的解释器.例如,如果调用的可执行脚本demo看起来像这样

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

printf "$]\n";
Run Code Online (Sandbox Code Playgroud)

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

$ ./demo
5.00503
% /usr/local/bin/perl-5.22 ./demo
5.022003
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

% /bin/bash ./demo-wc
$]
Run Code Online (Sandbox Code Playgroud)

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


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

zdi*_*dim 8

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

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

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

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

如果该#!行不包含单词"perl"或单词"indir",#!则执行以该命名的程序而不是Perl解释器.这有点奇怪,但它可以帮助那些不能做的人#!,因为他们可以告诉程序他们的SHELL是/ usr/bin/perl,然后Perl会将程序分派给正确的解释器.