Perl 如何处理 shebang 行?

How does Perl handle the shebang line?

我正在尝试了解 perl 如何处理 shebang 行。

曾经认为命令行"command position"中提到的任何解释器都优先于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 上的 "interpreter" 更改为 /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,执行 "overrule" shebang:

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

底线是 perl 似乎有完全不同的政策来处理 shebang,具体取决于提到的解释器。


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

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

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

If the "#!" line does not contain the word "perl" nor the word "indir" the program named after the "#!" is executed instead of the Perl interpreter. This is slightly bizarre, but it helps people on machines that don't do "#!", because they can tell a program that their SHELL is /usr/bin/perl, and Perl will then dispatch the program to the correct interpreter for them.

您的测试中有几个不同的案例。

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

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

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

If the #! line does not contain the word "perl" nor the word "indir", the program named after the #! is executed instead of the Perl interpreter. This is slightly bizarre, but it helps people on machines that don't do #!, because they can tell a program that their SHELL is /usr/bin/perl, and Perl will then dispatch the program to the correct interpreter for them.