Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Dev Hashbang

by Xiong (Hermit)
on Feb 19, 2010 at 14:10 UTC ( #824155=perlquestion: print w/replies, xml ) Need Help??
Xiong has asked for the wisdom of the Perl Monks concerning the following question:

My OS is partially written in Perl. I naively installed, with a free and easy hand, many CPAN modules into library directories searched by my system perl, for which I was justly paddled. I have paid heavy penance for my foolishness by wiping my drive and reinstalling my OS, formerly polluted by oddball modules. I now plan to compile another development perl executable (and dump modules into its library space with a will).

However, tooling along the street and meditating about my plans, I stumbled upon an issue. My current project will be deployed on a remote web server. To make scripts run on it, I begin each with the hashbang #!/usr/bin/perl -T. Up to now, that's worked equally well when testing such scripts on my local machine, since that is where the system perl resides.

But if I compile another executable, it will require a different hashbang, say #!/lab/perl -T. Otherwise, dev perl present or no, my script will run on the system perl. Then, when I upload the script, I'll have to edit the hashbang.

I don't want to do this. What now?

Updates: Fascinating TMTOWTDI here!

MakeMaker schemes annoy me, sorry. When in the Wallow, I tend to edit one file, reupload, test, scratch my head, repeat. I want to tighten that inner loop, not obtrude extra steps. (I'm sure some better than I have got this down to single keystrokes invoking tar and make.)

I lied. (s/#!([^\/]+)/perl/#!\/\1\/perl -T/) I have been setting -Taint on all my uploaded scripts, for good and obvious reasons. Silly of me not to consider this context as related. I'd better pass on env. (Initiates may meditate on the pratfall I took through inadequate Laziness and false Hubris in not simply copying an actual hashbang line from one of my scripts instead of glossing it by hand.)

pl2bat is not intended for my OS, thank Torvalds. It's just as well; otherwise I'd spend an hour figuring out what that line does. Maybe I should anyway.

Debian alternatives would work well in this case, as Ubuntu is descended from it; but given my non-linear work habits, I would probably omit someday to switch perls and Encounter a Nasty Bit in my Soup. I have not yet discovered just how much of my system is written in Perl, nor do I care to commit to a strategy that forbids future developers of dancing bear desktop applets to write them in Perl. Nice idea, though.

Symlinks look good. I'd thought briefly in that direction but not in the right way. With respect, I think perhaps the more obvious solution is on localhost to install /lab/perl, on remotehost symlink /lab/perl to /usr/bin/perl, and write the hashbang line #!/lab/perl -T. This requires no Extended Study Hall on my part; I know how to work symlinks. I merely didn't think hard enough. scorpio17++

More or less idiotically, I forgot that /dev/ is used to incorporate devices into the Linux file system.

Replies are listed 'Best First'.
Re: Dev Hashbang
by moritz (Cardinal) on Feb 19, 2010 at 14:19 UTC
    One way is to use #!/usr/bin/env perl
    which takes the first perl binary found in the $PATH environment variable. Then you have to tweak $PATH to point to the correct perl first on each platform.

      env is generally fine, but note that in this case you can't pass any arguments on the shebang line, because most kernels do split/pass everything after env as one argument.  For example

      #!/usr/bin/env perl -w ...

      would produce (on Linux)

      $ ./ /usr/bin/env: perl -w: No such file or directory

        Good point! particularily on a web server (as per the OP), where you want taint checks:

        !#/usr/bin/perl -T
        eval 'exec perl -x -S "$0" ${1+"$@"}' if 0; # In case running under some shell
        Easier to install with MakeMaker

      Thank you so much for that moritz. I've often wondered what env was for - its manpage does not do it justice. I'd given up trying to get bash to just run the perl it finds in $PATH.

Re: Dev Hashbang
by scorpio17 (Abbot) on Feb 19, 2010 at 15:01 UTC

    symbolic links to the rescue!

    On your development machine, install your custom perl in /usr/local, then make /usr/bin/perl a symbolic link to /usr/local/bin/perl like this:

    ln -s /usr/local/bin/perl /usr/bin/perl

    Then you can use the same shebang on both development and production servers.

    For modules, install everything into a local 'lib' directory, then use the line:

    use lib '/path-to-lib/lib';

    In all your scripts. Copy the lib directory to the production server, so that the scripts there will have access to the same libraries.

    For anything else, try to use config files. For example, say you want "debug mode" to be active on the development server, and not active on the production server.

    First create two files: dev-config.ini will contain the line:

    DEBUG = 1

    prod-config.ini will contain the line:

    DEBUG = 0

    Now create more symbolic links:

    On the development server:

    ln -s dev-config.ini config.ini

    On the production server:

    ln -s prod-config.ini config.ini

    So your scripts only need to read "config.ini", but it's one thing on the dev side and another on the prod side. Once you read the config file, you can do things like this in your script:

    if ($DEBUG) { # do debug stuff } else { # whatever }

    The idea is to make each server look as much the same as possible, so that you can just tar/zip the entire app directory on the development server, ftp it to the production server, and then unzip/tar it and everything work. With a little effort up front, it's definitely possible, and it makes life much easier.

Re: Dev Hashbang
by shmem (Chancellor) on Feb 19, 2010 at 14:44 UTC

    On many linux systems, there's the alternatives system.

    You can install various versions of perl, and switch to any of those using that; the hashbang remains the same for all (#!/usr/bin/perl). But beware - it is global. Take care to switch back to the defaults before running any system stuff that relies on perl (like apt, cron jobs etc).

Re: Dev Hashbang
by Anonymous Monk on Feb 19, 2010 at 14:15 UTC

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://824155]
Approved by marto
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (12)
As of 2018-02-18 19:12 GMT
Find Nodes?
    Voting Booth?
    When it is dark outside I am happiest to see ...

    Results (256 votes). Check out past polls.