tags:

views:

523

answers:

5

Which of these is better or faster to use as the shebang line for a Perl script?

#! perl

#! perl.exe

#! fullpath/perl(/perl.exe)

#! partialpath/perl(/perl.exe)

And, when using #!perl, when it works on a particular system, how do I find out in the script which perl interpreter I'm using so I can put that one into the shebang line?


And, if using a /path/path/perl, are "*" or "..." allowed to be used for the folders?

+3  A: 

A Windows (deducted from the perl.exe bit) she-bang seems irrelevant since your (ahum) 'shell' probably does not even parse it (correct me if I am wrong, could have been changed lately).

Some command line flags may still be picked up by Perl itself though (according to this thread).

ChristopheD
+3  A: 
  1. As ChristopheD noted, I can confirm from practice (ActivePerl on XP) that the shebang line is not really necessary on Windows.

    A shebang line tells a Unix shell which interpreter to pass the script to.

    On Windows, the program to pass the script to will be determined by associations based on the extension.

  2. On Unix, the third option (full path to perl executable) is best.

    And yes, you can use ".." in theory (shell doesn't care) but you should not really use relative path - you never know what your current working directory when executing a script will be.

DVK
+1  A: 

And, when using "#! perl", when it works on a particular system, what is the print() for showing the full path to perl.exe, that could be included into the Shebang Line ?

Well, if you're using the print statement you are already executing perl code, so...

klez
+8  A: 

If you have to hard code #!, use #!/usr/bin/env perl. Why? What you want is for the Perl program to run with the user's preferred Perl. That's going to be the first on in their PATH. #!perl doesn't do what I mean, it doesn't search the user's PATH, #!/usr/bin/env perl is how you pull that off. /usr/bin/env will always be there on Unix systems.

If the user is using Windows, as others have pointed out, it doesn't matter. Windows doesn't use #! it uses file extension associations. Make sure your program is called foo.pl or something and it'll work. But include the #! line anyway as some utilities and editors make use of it.

Otherwise, you should ship your program with some sort of installer. Both MakeMaker/Makefile.PL and Module::Build/Build.PL will change your #! line to match the perl the user used to install with. They will take care of this problem for you.

Schwern
On Unix, `#!/usr/bin/env perl` may cause a problem if there is more than one version of Perl on a computer. For example, a user account has `PATH` set to have another Perl ahead of `/usr/bin/perl`. The user logs in as "root". Then when root tries to run a system script, this actually runs the non-system perl. So system scripts should not use this.
Kinopiko
Reason #19382 to not ever log in as root. Use `sudo`. ;)
Schwern
Of course, not all unixes put env in /usr/bin.
jrockway
@Schwern: Why would `sudo` prevent this problem? The same thing would happen.
Kinopiko
@jrockway There's a certain point where there's only so much madness you can be expected to deal with. The list of systems which don't have /usr/bin/env is vanishingly small (http://www.in-ulm.de/~mascheck/various/shebang/#env) and if you're the poor admin of such a beast have hopefully symlinked /bin/env to /usr/bin/env
Schwern
@Kinopiko `sudo` retains your environment variables, such as `PATH`, unless you tell it otherwise. Anyhow, I agree that system scripts should have their paths hard coded.
Schwern
@Schwern - you forgot one thing - not all user's preferred `perl` binaries are named `perl` :( [ ours is perl5.8 ]
DVK
@DVK I didn't forget it, there's just little to be done about it. You've got to pick something, and perl is the most likely to work in the most places. How about symlinking perl5.8 to perl?
Schwern
@Schwern - in our case, 2 distinct versions of Perl are in use so no one right version to symlink to :(
DVK
@DVK Perl is backwards compatible, link to the latest one; it will have the best chance of running J Random Perl Script.
Schwern
@Schwern - Next time I'm root across 1000s of Unix servers, i'll keep that under consideration... but I'm just a developer with the root access of a caterpillar (sorry, that was a poor pun on real programmers and butterflies :) )... seriously, IIRC there were SOME incompatibilities between 5.005 and 5.8 but it's been a while since I remembered what they were. I can double check if you wish.
DVK
@Schwern, BTW, there's another problem with your suggestion in theory - newer Perl may not have been compiled with backwards-compatible @INC and thus not see every library other Perl does. Our newer Perl doesn't suffer from that issue in practice, but that's due to better than average foresight :)
DVK
@DVK You're right, there are minor incompatibilities, and we could nit pick them all day. Now, which is better: not having anything called "perl" in your path and having no chance of running scripts looking for "perl", and having something called "perl" in your path (you don't need to be root to put a perl symlink in your path) and having a good chance?
Schwern
@Schwern - I think we are thinking in different modes to some extent. I'm thinking global corporate production deployments... you seem more angling for someone's own Unix/Linux environment... in the latter case I'd agree with you, in the former case it's way too un-producton-like if you will, IMHO...
DVK
+1  A: 

This is one of the things which I dislike about Perl.

On Windows, if you are using ActiveState Perl at least, if the file ends with .pl then the Windows registry will run the Perl interpreter for you, regardless of the shebang line. On Cygwin, I am not sure why but #! perl works too. On Unix you should put the full path to your Perl executable in the shebang line. Schwern's idea of using env is convenient, but has some danger, as I pointed out in a comment.

This is why I suggest to you that the best solution is to package your Perl scripts as CPAN modules. CPAN installers like Module::Build will then change the shebang line to the full path to your Perl interpreter. (I am not sure whether Schwern's installer, ExtUtils::MakeMaker, does this or uses env, since I don't use it.)

Kinopiko
The Module::Build #! fixup code came from MakeMaker which came from the pink Camel book. They all hard code the path to perl.
Schwern