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

xxk*_*kkk 0 shell perl

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

旧作品版

#!/bin/perl
eval 'exec perl5 -S $0 ${1+"$@"}'
   if 0;
Run Code Online (Sandbox Code Playgroud)

新版本不起作用

#!/bin/sh
eval 'exec perl5 -S $0 ${1+"$@"}'
   if 0;
Run Code Online (Sandbox Code Playgroud)

请注意,我改#!/bin/perl#!/bin/sh和基于我的理解,新版本也应该工作,因为该脚本将被视作shell脚本,并eval得到执行和perl5被调用来使用Perl来执行相同的脚本.但是,当我实际运行时,我得到了:

/bin/sh: -S: invalid option
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么这种情况脚本失败.我误解了什么吗?我正在使用ksh

我在网上找到的这个网页似乎也暗示我的新版本应该也能正常工作.

非常感谢!

ike*_*ami 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因为它看到一个不包含的shebang perl.
  5. sh因为它无法识别-S选项而死亡.

如果您启动修改后的版本perl5 script:

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

我在网上找到的这个网页似乎也暗示我的新版本应该也能正常工作.

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