in reply to wrapper script to conditionally exec different perls?

Note that if you have NFS problems, -x "/path/to/perlY" may take a really long time, so doing this check for every invocation of a program that expects to be run by perl may be confusing to users.

How did your second approach fail, and why? I'm not exactly sure what error conditions there are that would make it fail. Maybe you need to add the invoked script name $0 after perlX in the command line, unless the argument is -e? You might need to (re)implement a Perl option parser for that, mostly from perlrun to mirror that.

Replies are listed 'Best First'.
Re^2: wrapper script to conditionally exec different perls? (#!->#!->#!->...)
by tye (Sage) on Feb 15, 2012 at 18:55 UTC

    I bet most kernels don't support having a #! line in a script that points to another script that has another #! that points to another thing. You see how that could quickly get rather convoluted.

    Unfortunately, when I try to do that myself to test it, rather than a nice clear error message telling me not to be such a clever prick, I get errors that look like my Perl script is being interpreted by something other than perl but I am, so far, at a loss as to what that other thing is.

    When I ran "strace script" to figure out what other thing is trying to interpret my Perl code, I got "exec: Exec format error" from strace.

    So, one answer for the OP is to write this simple wrapper in a compiled language so that the wrapper doesn't need a #! of its own.

    - tye        

      Tye proposed using a compiled language for the wrapper program. Indeed, a simple C program performs the desired wrapping perfectly. Thanks much!

      I suspect my problem had to do with something being run via "sh -c", even when my wrapper was a perl script. I got the same "exec: format error" that Tye did when strace'ing my script.

      most kernels don't support having a #! line in a script that points to another script

      While this is correct in general, it's maybe worth pointing out that newer versions of the Linux kernel (as of 2.6.27, IIRC) can actually handle this fine (finally!).   I.e., things like these do in fact work:

      ---  perl-wrapper  ---

      #!/usr/bin/perl my $choice = splice @ARGV,1,1; exec '/usr/local/perl/5.14.1/bin/perl', @ARGV if $choice == 14; exec '/usr/local/perl/5.12.3/bin/perl', @ARGV if $choice == 12; exec '/usr/local/perl/5.10.1/bin/perl', @ARGV if $choice == 10; exec '/usr/local/perl/5.8.8/bin/perl', @ARGV;

      ---  wrap-test.pl  ---

      #!/home/eliya/tmp/perl-wrapper print "$] -- @ARGV\n";
      $ ./wrap-test.pl 14 foo bar 5.014001 -- foo bar $ ./wrap-test.pl 12 foo bar 5.012003 -- foo bar $ ./wrap-test.pl 10 foo bar 5.010001 -- foo bar $ ./wrap-test.pl 99 foo bar 5.008008 -- foo bar

      (the technique to use the first arg as version selector is of course just for demo purposes)

      P.S.: side note for anyone playing with this: make sure you have the string "perl" in the shebang line, or else you'll get surprising effects like endless exec loops... — see perlrun for why (search for the word "bizarre").

Re^2: wrapper script to conditionally exec different perls?
by stackspace (Initiate) on Feb 15, 2012 at 22:06 UTC

    Thanks. I was too lazy to specify what went wrong when I replaced the bash "exec" script (meant to be /usr/bin/perl; let's call it "mywrapper") with a perl "exec" script. Here's what happened.

    "mywrapper -v" produced the desired output, showing that the correct perl binary was invoked (perlY if perlY available, else perlX).

    helloworld.pl is this:

    #!/path/to/mywrapper use strict; print "Hello World!";

    "/path/to/mywrapper helloworld.pl" caused helloworld.pl to run properly.

    But executing helloworld.pl yields

    line 3: use: command not found line 5: print: command not found