http://www.perlmonks.org?node_id=825147

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

Here's a construct stinking to me of the multiplatform workpla¢e. This is the top of a cpan script newly created (by $ /lab/bin/perl -MCPAN -eshell) for the purpose of downloading modules into my development perl only under Linux:

#!/lab/bin/perl eval 'exec /lab/bin/perl -S $0 ${1+"$@"}' if $running_under_some_shell; #!/usr/bin/perl

... followed by what looks like reasonable Perl code.

Two questions:

1. Practically, can I replace this gubbins with one clean hashbang line?

2. Academically, what exactly is going on here?

perlrun (near -S):

#!/usr/bin/perl eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}' if $running_under_some_shell;

and the even more baroque:

eval '(exit $?0)' && eval 'exec perl -wS $0 ${1+"$@"}' & eval 'exec /usr/bin/perl -wS $0 $argv:q' if $running_under_some_shell;

Gloss on above from MadMongers is notable for the hints:

Yeah, that's a winx thing... ...the first part of the script is both (ba)sh and perl acceptable...

Something Google sucked into its archives uses a similar deal several times in one file, if i read aright:

sed "s/^X//" >'dbdump' <<'END_OF_FILE' X: #!/usr/bin/perl Xeval 'exec /usr/bin/perl -S $0 ${1+"$@"}' X if $running_under_some_shell; X#!/usr/local/bin/perl

The Camel 24.5.1. Generating Other Languages in Perl (so I guess this is official):

print &q(<<"EOT"); : #!$bin/perl : eval 'exec $bin/perl -S \$0 \${1+"\$@"}' : if \$running_under_some_shell; : EOT

Grokbase startperl insanity:

print OUT <<"!GROK!THIS!"; $Config{startperl} -- # -*- perl -*- eval 'exec $Config{perlpath} -S \$0 \${1+"\$@"}' if \$running_under_some_shell; !GROK!THIS!

This last is noteworthy in that -*- (seen in perlrun) is explained to be not merely a whimsical example but a bonafide workaround for some terrible weirdness:

By the time there's the -*- perl -*- in place, the #! redispatcher code is happy, in that it doesn't attempt to re-exec. Adding another #!perl and an -x earlier doesn't seem to make a difference. Taking out the -*- perl -*- causes an infinite loop

This page also has the charming metasyntactic variable I employ with relish in this post.

Finally, from an older copy of the cpan script on my very own machine:

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

This annoys me thrice. There's something blatant about if 0; the comment seems to invert the test relative to previous examples; this script is generated to run on a Linux box known to interpret hashbangs correctly.

I gather that the test, both here and in other examples, will not execute under most shells but the preceeding eval will; while perl will execute the test and ignore the eval.

I also gather that command-line arguments are being passed through to perl when the shell executes; but then why the 1+? How, in the 21st Century, did this 19th Century springloaded contraption come to spray tiny oily sprockets across my workbench?

My conclusions are: Yes, I can lop off this gubbins and replace it with one honest hashbang; and Blame Micro$oft. Please correct, expand, and illuminate.

Update:

Corion, thank you++ for that detail. Of course this still leaves open the question of why such an obscure approach is required. In a way, it's worse, all in the family. Can't all shell authors agree on one idiom for dispatching scripts?

rubasov, thank you++ for the extremely detailed breakdown. Practically, I don't have to know what this thing does to delete it. It's a curiosity, though; an itch I had to scratch.

One wonders how long a script could be written that would execute (differently but without error) under how many shells and interpreters. Upvote ambrus for a strong effort but I was thinking of something a tad bit more audacious. Topic for another node...

And yes, thank you++ shmem. It's always good to hear the other side of the issue. Complacency is a greater threat to excellence than ignorance.