j1n3l0 has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks,

Something of a novice question. Was looking through the source for some executable perl programs (cpan, module-starter, etc ...) and I noticed that they all start as follows:

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

My question is what exactly is going on there (especially here: $0 ${1+"$@"}) and how important is it?


Smoothie, smoothie, hundre prosent naturlig!

Replies are listed 'Best First'.
Re: Executable perl programs
by Corion (Patriarch) on Mar 23, 2008 at 19:51 UTC

    This is the Magic Perl Header.

    It is code that is a (meaningful) shell program and a nonsensical Perl program and mostly re-executes the program with perl if it finds that it was launched as a shell script.

      I'm curious too. The guy is asking for a break-down of what's happening in that little piece of code. I know that $0 is Perl's special variable for the program being executed but what's going on with ${1+"$@"}? The linked article describing the "magic" doesn't explain it.

        Under Perl, the first line together with the second line is simply a syntactically valid statement that will never be executed. Under the shell, only the first line will ever be seen and executed by the shell. The shell will interpret the line as

        eval 'exec perl -S -x -- "$0" ${1+"$@"}'

        where $0, quite unsurprisingly, will be replaced by the name of the perl program. $@ expands to the quoted list of arguments and ${1+"$@"} seems to be a fancy shell way of writing "$@". See the article I already linked, the section titled Problems 1--3 can be overcome quite easily:, from which I took this whole discussion. For the rest, see your shell manual.

Re: Executable perl programs
by CountZero (Bishop) on Mar 23, 2008 at 19:34 UTC
    What kind op OS do you run? On my Windows XP Pro and ActiveState Perl 5.8.8, these perl programs start with the usual (but on Windows not really needed) #!/usr/bin/perl -w

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

      Sorry, this is on a Linux machine. Although its the same on my Mac OS X and on Windows XP the cpan.bat file starts like this:

      @rem = '--*-Perl-*-- @echo off if "%OS%" == "Windows_NT" goto WinNT perl -x -S "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9 goto endofperl :WinNT perl -x -S %0 %* if NOT "%COMSPEC%" == "%SystemRoot%\system32\cmd.exe" goto endofperl if %errorlevel% == 9009 echo You do not have Perl in your PATH. if errorlevel 1 goto script_failed_so_exit_with_non_zero_val 2>nul goto endofperl @rem '; #!perl #line 15 eval 'exec C:\strawberry\perl\bin\perl.exe -S $0 ${1+"$@"}' if $running_under_some_shell;


      Smoothie, smoothie, hundre prosent naturlig!