Reputation: 37
I'm new to Perl and was hoping someone could tell me what this means exactly
eval 'exec ${PERLHOME}/bin/perl -S $0 ${1+"$@"}' # -*- perl -*-
if 0;
Upvotes: 0
Views: 321
Reputation: 1007
I just read @Zaid's response, which is better and more correct than mine as long as this code is on the first line of the script being executed, and no shebang exists. I've never seen this kind of substitute. Quite interesting, really.
The second line, if 0;
is a part of the first line. You can tell since the first line lacks a ;
. It would be more obvious if this was one long single line with the comment being after the semicolon.
So it's equivalent to:
if(0) {
eval 'exec ${PERLHOME}/bin/perl -S $0 ${1+"$@"}
}
In perl, 0 will be evaluated to false, and so the eval-clause will never execute. Presumably this condition(the if
) was a quick way to disable the line. Perhaps the evaluation was once something real instead of an always-false.
See perl --help
, perldoc -f eval
and perldoc -f exec
for information on the evaluation block itself.
The remaining trickyness (${1+"$@"}
) I have no idea about. This isn't perl anyway; it's interpreted by whichever shell exec
is launching (Correct me if I'm wrong on this!). If it's bash, I don't think it does anything at all and can be substituted with $@, which is the environment variable holding all commandline arguments (ie @ARGV in perl).
Upvotes: 0
Reputation: 37136
This is explained in perldoc perlrun
:
-S
makes Perl use the PATH environment variable to search for the program unless the name of the program contains path separators.
...
Typically this is used to emulate
#!
startup on platforms that don't support#!
. It's also convenient when debugging a script that uses#!
, and is thus normally found by the shell's$PATH
search mechanism.This example works on many platforms that have a shell compatible with Bourne shell:
#!/usr/bin/perl eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}' if $running_under_some_shell;
The system ignores the first line and feeds the program to
/bin/sh
, which proceeds to try to execute the Perl program as a shell script. The shell executes the second line as a normal shell command, and thus starts up the Perl interpreter. On some systems$0
doesn't always contain the full pathname, so the-S
tells Perl to search for the program if necessary. After Perl locates the program, it parses the lines and ignores them because the variable$running_under_some_shell
is never true. If the program will be interpreted bycsh
, you will need to replace${1+"$@"}
with$*
, even though that doesn't understand embedded spaces (and such) in the argument list. To start upsh
rather thancsh
, some systems may have to replace the#!
line with a line containing just a colon, which will be politely ignored by Perl.
In short, it mimics shebang behavior for platforms that have shells compatible with Bash.
Upvotes: 4
Reputation: 189377
It's valid both as shell script and as a Perl program. It is used to run the Perl interpreter after all on systems where the shebang doesn't work, for some reason. It's rarely seen these days but used to be common in the early 1990s.
The comment is just a comment, but it has special meaning in Emacs, which will open the file in perl mode.
Upvotes: 1