6

In many perl scripts (especially in famous CPAN distros) I find the following piece of code:

eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
if 0; # not running under some shell

I was wondering what it is for?

Thanks.

Беров
  • 1,383
  • 10
  • 22

2 Answers2

9

Some systems don't recognize the #!/usr/bin/perl line at the start of scripts, and so trying to invoke a Perl program by name on such a system will simply pass the script to the shell. In order to combat this, portable Perl programs begin with a line that, when interpreted by a standard POSIX shell, causes the script to be passed to perl(1) instead. The if 0 causes the line to be ignored when run by Perl itself, and placing it on a separate line causes shells to treat it as a separate command, running just the eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}' as soon as it's read.

jwodder
  • 54,758
  • 12
  • 108
  • 124
  • Thanks, very much! How clever really! – Беров Feb 04 '12 at 19:30
  • 1
    I wonder if there are still any systems worth worrying about that don't support [shebangs](http://en.wikipedia.org/wiki/Shebang_(Unix)). – Keith Thompson Feb 04 '12 at 19:50
  • 2
    I have scripts that do this so that they will run under Solaris AND Linux. The shebang points to a Solaris perl, but under Linux the script executes as shell, and the eval line executes a Linux perl. The perls are installed under odd locations, but files/directories are shared between systems via NFS. – runrig Feb 04 '12 at 22:44
2

The line is valid under shells as well as perl. In perl eval is skipped because of following if 0. In shell, same file is executed in perl using the eval.

bvr
  • 9,687
  • 22
  • 28