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

There is strange string at the beginning of the Perl script I have.
eval '(exit $?0)' && eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}' && eva +l 'exec /usr/bin/perl -wS $0 $argv:q' if 0;
Looks like currently it doesn't have effect due to "if 0" at the end. I'm wondering if I can remove it. I'm tryin to understand the intention of string without "if 0" in order to decide it I need it or not. Could someone please describe in steps what is dome here and for what?
  • Comment on What is the intention and logic of this line in the beginning of the script?
  • Download Code

Replies are listed 'Best First'.
Re: What is the intention and logic of this line in the beginning of the script?
by moritz (Cardinal) on Oct 12, 2011 at 09:53 UTC

    The if 0; is usually done to prevent Perl from running what comes before it, but shells still interpret it.

    So what comes before it must parse as valid Perl code, and execute as valid shell code.

    The usual use case is to call perl to execute the current script if it was accidentally executed by a shell.

Re: What is the intention and logic of this line in the beginning of the script?
by cdarke (Prior) on Oct 12, 2011 at 10:33 UTC
    As moritz said, this is actually a shell command. eval is both a shell and a Perl command, but in this case it is the shell version.

    In most UNIX shells (not csh), $? is the status of the previous command (in Perl it is the exit status of the previous child process - not the same thing). In a shell, parentheses create a sub-shell which is a new shell environment (I use the term loosly) in the same process, so eval '(exit $?0)' in shell exits the sub-shell (not the current process). In shells, an evaluation of non-zero is considered false, and 0 is considered true (consider 0 to be 'success').

    exec also is in both shells and Perl, and it replaces the current program with a new one in the same process, so it will replace the shell with perl.

    In this case, the if 0 will be considered part of the command by a shell. However, in Perl the if 0 has precedence, so none of that will be executed if we are running perl, zero being false in perl (and most languages). Try:
    print "A " && print "B " && print "C " if 0;
Re: What is the intention and logic of this line in the beginning of the script?
by Anonymous Monk on Oct 12, 2011 at 10:20 UTC
Re: What is the intention and logic of this line in the beginning of the script?
by dd-b (Pilgrim) on Oct 12, 2011 at 19:23 UTC

    It's implicit in what others have said, but just to make it explicit -- the purpose of that line is so that if the file accidentally gets run by a shell, it will still end up running in Perl.