更改shebang + eval会导致perl脚本失败

时间:2016-07-17 15:13:42

标签: perl shell

这个问题来自另一个post。根据该帖子的评论和回答,我将以下shebang + eval更改为另一个:

旧作品

#!/bin/perl
eval 'exec perl5 -S $0 ${1+"$@"}'
   if 0;

新功能不起作用

#!/bin/sh
eval 'exec perl5 -S $0 ${1+"$@"}'
   if 0;

请注意,我将#!/bin/perl更改为#!/bin/sh,根据我的理解,新版本也应该有效,因为脚本被视为shell脚本并且eval被执行并{{1调用使用perl来执行相同的脚本。但是,当我实际运行时,我得到了:

perl5

任何人都可以解释为什么这种情况下脚本失败了。我误解了什么吗?我正在使用/bin/sh: -S: invalid option

我在网上找到的这个web page似乎也暗示我的新版本也可以正常运行。

非常感谢!

1 个答案:

答案 0 :(得分:9)

来自Perl文档:

  

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

因此,如果您将修改后的版本启动为./script

  1. 您的shell执行./script
  2. 内核实际执行/bin/sh ./script
  3. sh执行perl5 -S ./script
  4. perl5执行/bin/sh -S ./script,因为它会看到一个不包含perl的shebang。
  5. sh因为无法识别-S选项而死亡。
  6. 如果您将修改后的版本启动为perl5 script

    1. 您的shell执行perl5 script
    2. perl5执行/bin/sh -S script,因为它会看到一个不包含perl的shebang。
    3. sh因为无法识别-S选项而死亡。
    4.   

      我在网上找到的这个网页似乎也暗示我的新版本也应该可以使用。

      该页面上的代码与您使用的代码明显不同。在该代码中,有一个显式指令(-x)来忽略实际的shebang行,并在文件后面查找包含perl的指令(代码中也缺少该代码)。