2017-08-29 75 views
1

我想了解perl如何处理shebang线。Perl如何处理shebang行?

认为,在命令行中的“命令位置”中提到的任何解释将采取优先于家当行中提到之一。例如,如果一个可执行脚本调用demo看起来像这样

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

printf "$]\n"; 

...然后我会注意以下事项:

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

督察,在第一次执行,在家当解释是一个在运行,而在第二个是在命令行中提到的那个。到现在为止还挺好。

但现在,如果我改变对认领的“翻译”成类似/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,做“否决”的家当:

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

的底线是perl似乎有处理取决于提到解释的家当完全不同的策略。


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

已经在这里回答:https://stackoverflow.com/a/29563961/152948 – hobbs

+1

@hobbs不完全,这回答了问题的一部分。 – zdim

回答

6

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

当你使用./demo...时,内核在幻数(前16位)中找到#!并运行该程序,或者在失败时将该行传递给shell,从而启动它。

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

如果shebang不是而不是调用perl,我们对Perl有特殊的行为。 从perlrun

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

1

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

详情请参阅perlrun手册页。您的相关部分是这样的:

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