Gregory Nisbet Gregory Nisbet - 1 year ago 60
Perl Question

How does Perl avoid shebang loops?

interprets the shebang itself and mimics the behavior of
. I think it emulates the Linux behavior of splitting on all whitespace instead of BSD first-whitespace-only thing, but never mind that.

Just as a quick demonstration

#!/usr/bin/env python

# the following line is correct Python but not correct Perl
from collections import namedtuple
print "hi"

prints hi when invoked as

Also, the following programs will do the right thing regardless of whether they are invoked as
perl program

print "hi\n";


#!/usr/bin/env perl
print "hi\n";

I don't understand why the program isn't infinite looping. In either of the above cases, the shebang line either is or resolves to an absolute path to the
interpreter. It seems like the next thing that should happen after that is
parses the file, notices the shebang, and delegates to the shebang path (in this case itself). Does
compare the shebang path to its own
? Does
look at the shebang string and see if it contains
as a substring?

I tried to use a symlink to trigger the infinite loop behavior I was expecting.

$ ln -s /usr/bin/perl /tmp/p

print "hi\n";

but that program printed "hi" regardless of how it was invoked.

On OS X, however, I was able to trick
into an infinite shebang loop with a script.

Contents of

perl "$@"

Contents of perl script

print "hi\n";

and this does infinite loop (on OS X, haven't tested it on Linux yet).

is clearly going to a lot of trouble to handle shebangs correctly in reasonable situations. It isn't confused by symlinks and isn't confused by normal
stuff. What exactly is it doing?

Answer Source

The documentation for this feature is found in perlrun.

If the #! line does not contain the word "perl" nor the word "indir", the program named after the #! is executed instead of the Perl interpreter. This is slightly bizarre, but it helps people on machines that don't do #!, because they can tell a program that their SHELL is /usr/bin/perl, and Perl will then dispatch the program to the correct interpreter for them.

So, if the shebang contains perl or indir, a new interpreter isn't executed.

Additionally, the interpreter isn't executed if it's the same as $^X. How $^X is set varies by system, explaining the differences you observed.