A change of shebang + eval leads to the perl scrip

2019-09-13 19:25发布

This is a question derives from another post. Based upon the comments and answer from that post, I change the following shebang + eval into another one:

Old works version

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

New doesn't work version

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

Notice that I change #!/bin/perl to #!/bin/sh and based upon my understanding, the new version should also work because the script is treated like shell script and eval get executed and perl5 is invoked to use perl to execute the same script. However, when I actually run this, I got:

/bin/sh: -S: invalid option

Can anyone explain why this case the script is failed. Do I misunderstand something? I'm using ksh

Also this web page I found online seems suggest that my new version should work as well.

Thanks much!

标签: perl shell
1条回答
神经病院院长
2楼-- · 2019-09-13 19:33

From the Perl documentation:

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.

So if you launch the modified version as ./script:

  1. Your shell executes ./script
  2. The kernel actually executes /bin/sh ./script
  3. sh executes perl5 -S ./script
  4. perl5 executes /bin/sh -S ./script because it sees a shebang that doesn't contain perl.
  5. sh dies because it doesn't recognize the -S option.

And if you launch the modified version as perl5 script:

  1. Your shell executes perl5 script
  2. perl5 executes /bin/sh -S script because it sees a shebang that doesn't contain perl.
  3. sh dies because it doesn't recognize the -S option.

Also this web page I found online seems suggest that my new version should work as well.

The code on that page is significantly different than the code you used. In that code, there's an explicit instruction (-x) to ignore the actual shebang line, and to look for one that contains perl later in the file (which is also missing from your code).

查看更多
登录 后发表回答