Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Long eval string at the beginnning of Perl script

Tags:

perl

eval

I am relatively new to Perl and am working on Perl files written by someone else, and I keep encountering the following statement at the beginning of the scripts:

eval '(exit $?0)' && eval 'exec perl -w -S $0 ${1+"$@"}' && eval 'exec perl -w -S $0 $argv:q'
  if 0;

What do these two lines do? What is the code checking? and What does the if 0; sentence do?

like image 690
Amelio Vazquez-Reina Avatar asked Sep 08 '12 00:09

Amelio Vazquez-Reina


People also ask

What is $@ in Perl?

$@ The Perl syntax error or routine error message from the last eval, do-FILE, or require command. If set, either the compilation failed, or the die function was executed within the code of the eval.

What is eval in Perl script?

The eval function takes a character string, and evaluates it in the current perl environment, as if the character string were a line in the currently executing perl program.

What does Perl eval return?

The eval block is parsed with the rest of the code and its return value is a reference to the array @a . That reference is assigned to $ttt . While the eval block goes out of scope, @a still has a non-zero reference count (thanks to $ttt ) so it still exists.


1 Answers

This is a variant of the exec hack. In the days before interpreters could be reliably specified with a #!, this was used to make the shell exec perl. The if 0 on the second line is never read by the shell, which reads the first line only and execs perl, which reads the if 0 and does not re-execute itself.

This is an interesting variant, but I think not quite correct. It seems to be set up to work with either the bourne shell or with csh variants, using the initial eval to determine the shell that is parsing it and then using the appropriate syntax to pass the arguments to perl. The middle clause is sh syntax and the last clause is appropriate for csh. If the second && were || and the initial eval '(exit $?0)' did actually fail in csh, then this would accomplish those goals, but as written I don't think it quite works for csh. Is there a command that precedes this that would set $? to some value based on the shell? But even if that were the case and $? is set to a non-zero value, then nothing would be exec'ed unless the && is replaced with ||. Something funny is happening.

like image 149
William Pursell Avatar answered Oct 20 '22 00:10

William Pursell