Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Calling the correct perl binary

by cavac (Parson)
on Apr 01, 2011 at 23:22 UTC ( [id://897028]=perlmeditation: print w/replies, xml ) Need Help??

Note: I didn't write this post to start a flame war or to discredit anyone. What i like to see is some active discussion on the topic

On most of my (linux) systems, i usually have at least two perl binaries installed:

  • Whatever comes with the linux distribution, usually at /usr/bin/perl
  • The one that i use. That's the one a call to "perl" starts in *my* user account

In the past - when using the OS supplied perl - i had some major troubles. Mostly, these where incompatibilities after the distributor rolled out some updates or when i upgraded some modules to newer (test) versions. Also, now i use ActiveState Perl for much of my software development.

The trouble is: While the distribution-supplied scripts correctly call /usr/bin/perl, most of the code that i download from the interwebs does so too - and start breaking because of "missing" modules

The thing that worked for me best is to change all Perl scripts on my system to use
#!/usr/bin/env perl
as the hashbang line. Whenever the systems automatically start a Perl script, it uses the dristribution-maintained perl, whenever i start a script with my user account, it uses the perl installed in my home directory.

In my opinion, in a time where there are more and more different plattforms, assuming perl is at a fixed path and that perl binary is the correct one to use isn't very helpfull. It's similar to the still widely spread believe that /bin/sh is bash (or csh or whatever)...

Replies are listed 'Best First'.
Re: Calling the correct perl binary
by Tanktalus (Canon) on Apr 02, 2011 at 02:01 UTC

    If I download code and install it via Makefile.PL or Build.PL, then the perl that runs the .PL gets to be the perl that runs the resultant code. If I download code and it just wants to "be", it's either an all-in-one version of ack, or it's probably not something I want to use anyway.

    I have a bunch of perls installed in ~/perl/$version/bin - and I use Gentoo's eselect with a custom-written (shell) module that creates ~/bin/lperl ("l" for "local") as a hardlink to the current perl (and lperldoc and lcpan). If I write a script I want to use a particular version, I put in "#! $myhomedir/perl/5.12.2/bin/perl" at the top, and I'm done. If I want to test against a bunch of perls, I use "#! $homedir/bin/lperl", and then I can just swap the hardlink ("eslect lperl set 5.12.2" - tab completion works here).

    In $work-related code, I absolutely must use perl 5.8.8, which I'm none-to-happy with, but I digress. I actually export DEV_PERL="~/bin/perl5.8.8" (which is also a hardlink over to the perl 5.8.8 in ~/perl/5.8.8/bin), and then I put code like this at the top:

    # -*-perl-*- # Allow people to override the perl location with a real perl of the r +ight level eval 'exec ${DEV_PERL:-/usr/bin/perl} -S $0 "$@"' if 0;
    This will default to being run by the shell, which will ignore the first three lines, see the next line as "eval <code>" and eval that code, which is to exec (replace itself with) perl, with the same parameters as before (the -S tells perl it may need to check PATH - never tested if that's really needed or not). Perl comes along, ignores the first three lines again, sees the eval, but then keeps going to the semicolon, and sees it's an "if 0", and should pretty much eliminate that line during compilation. The shell never sees the rest of the code.

    So, you can see I use multiple approaches. Because I've not found any one approach to be obviously better in all circumstances, but different needs will result in different solutions. Here is where a good understanding of how your operating system figures out how to run a script comes in handy, plus some decent shell knowledge that can give you more options.

    Note that you should assume /bin/sh is bourne shell. Any other assumption is dangerous. Even some ksh's and bash's operate a bit differently when they see they're called as "sh" instead of "ksh"/"bash".

    (PS - you can't actually use $myhomedir in the #! line - it's just a shortcut for my home directory, if you copy my ideas, you'll have to modify for your home directory.)

      Thanks for your input. This gives me some more options for experimenting!
      Don't use '#ff0000':
      use Acme::AutoColor; my $redcolor = RED();
      All colors subject to change without notice.
Re: Calling the correct perl binary
by JavaFan (Canon) on Apr 03, 2011 at 22:49 UTC
    Whenever the systems automatically start a Perl script, it uses the dristribution-maintained perl, whenever i start a script with my user account, it uses the perl installed in my home directory.
    What's the purpose of that? For a script, there are four possibilities:
    1. It will only run with the "system" perl.
    2. It will only run with "your" perl.
    3. It will run with either perl.
    4. It won't run with any perl.
    For the first two cases, using the 'env' trick is wrong - the path should be hardcoded. For the other two cases, the 'env' trick doesn't gain you anything.

    So, why use it?

    Note also that not every system has 'env', the systems that have it don't all have it in the same path, and that many 'env's cannot pass arguments. So, using the 'env' trick to make things more portable isn't very fruitful.

      I'm aware that the env "trick" isn't completly portable. But neither is assuming that perl is available under /usr/bin/perl. Not when so many new plattforms/operating systems enter the market these days. There are probably hundreds of companies and lonely geeks out there hacking some new, cool operating systems for their future tablets, smart(er) phones, e-book readers, industrial robots... and probably some cool gadgets not yet officially invented.

      I think you miss my point. By essentially hardcoding which perl to use, you take away many possibilities. Like having a user run/test all the scripts with a different perl binary.

      Of course, the user could alway call /mypath/perl somescript.pl. But that's not always possible. Especially if - say for example - a bash script starts the Perl script. And yes, you could always rewrite the scripts and such. To me, it makes more sense to just set some environment variables *once* and let the system to the actual work.

      And.. another yes, most of my scripts run well on both on the system perl as well as "my own" (but i wont risk it on production systems). Testing is easy enough, i just run a bash script that changes the environment variables and i can test all of my Perl scripts on all of my installes perl binaries - without rewriting them.

      So, sorry for the rant, but there currently is no 100% portable way to implement calling the correct binary for perl. But hardcoding the full path to which perl binary to use is - in my opinion - even less helpfull.

      Don't use '#ff0000':
      use Acme::AutoColor; my $redcolor = RED();
      All colors subject to change without notice.
        But hardcoding the full path to which perl binary to use is - in my opinion - even less helpfull.
        And your solution is to replace it with another hardcoded path?

        What makes you think that those new, cool platforms you are referring to have an env, and it's in the location you presume it is? I mean, if they deliver their new, cool platform, with a perl, not in /usr/bin, but elsewhere in $PATH, they may as well have env elsewhere as well.

        You seem to have a perceived problem, which you are fixing with a solution that suffers from exactly the same potential problem.

Re: Calling the correct perl binary
by Anonymous Monk on Apr 02, 2011 at 01:43 UTC
    Note: I didn't write this post to start a flame war or to discredit anyone. What i like to see is some active discussion on the topic

    Have you sought out previous discussions?

    The trouble is: While the distribution-supplied scripts correctly call /usr/bin/perl, most of the code that i download from the interwebs does so too - and start breaking because of "missing" modules

    So change the shebang? This is done automatically when you do

    perl Makefile.PL make install
Re: Calling the correct perl binary
by sundialsvc4 (Abbot) on Apr 04, 2011 at 17:54 UTC

    The same thing can happen in-general when you’re deploying Perl scripts to shared-hosting web hosts.   You basically wind up with unwanted dependencies upon “the globally-installed Perl,” which results in code that works here but doesn’t work there.   Or, a deployed and running website that conks out because of something that you didn’t have anything at all to do with, any notification of, or any control over.   (They always seem to make those changes at ungodly hours of the night.)

    Indeed, the only way to obtain code that will reliably work when deployed, and that will reliably continue to work wherever deployed, is to make that deployment be completely self-contained.

    I would love to know of a tool – and I am quite sure it is well-known (but not yet to me) – that, when pointed to the code in a particular directory, will locate all of the references to external packages that will be resolved by packages “in the environment,” that is to say, “outside of those directories which I designate.”   It would likewise be useful if that tool scanned for “shebang” references outside.   And it would be really useful if the module that did all of this usefulness was a Test::.

    All of which means, no doubt, that surely there is just such a Test:: package... oui?

Re: Calling the correct perl binary
by clp (Friar) on Apr 05, 2011 at 05:31 UTC
    I recently ran across perlbrew, which might help with this issue; haven't used it yet myself.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://897028]
Approved by ww
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2024-03-19 11:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found