[sf-perl] dynamic #! line

Joe Brenner doom at kzsu.stanford.edu
Mon Mar 23 20:36:56 PDT 2009


Matthew Lanier <matt at lanier.org> wrote:

> i'm in a situation where I may need to set #! on a perl script at run time
> via the environment.  I know that's technically possible, but am unsure
> what hidden gotchas may result.  Any thoughts on that?

Have you checked the "perlrun" manpage?

When this subject came up back in 2003, there were essentially
four ideas discussed:

(1) wrapper programs that change the hashbang line (e.g. a C program)
(2) add symlinks to the system so that perl is found in multiple places
(3) using a "sh" hashbang that then runs perl
(4) the env trick

I'm appending some messages from the 2003 thread:

===

Date: Fri, 10 Jan 2003 16:09:31 -0800
From: John Tannahill <tannahill1 at llnl.gov>
To: sfpug at sf.pm.org
Subject: [sf-perl] [Fwd: [Fwd:perl scripting]]

It's my understanding that your group does a lot of Perl script
writing.  Over the years, I have written some perl scripts to
serve as utilities for the code that I work on.  The problem
that I ran into is with the typical first line of a perl script:

  #!/usr/bin/perl

We run on many different machines and unfortunately it turned
out that perl wasn't always in /usr/bin.  Sometimes it is in
/usr/local/bin or it could in theory be anywhere the system
people want to put it.

The solution we implemented was to put a C-Shell wrapper
around each perl script which checks to see where perl is and
then rewrites the perl script to a seperate file with the
correct first line and executes it.  This works, but it is
pretty unwieldy and ugly.  Perhaps you or someone in your
group knows a simple remedy for this issue?  Or maybe you can
point to someone who might?

The C-Shell wrapper looks like this:

#

#--------------------------------------------------------------------------
# The statements above, immediately below, and at the very end of this file
# were added to make this script more portable, as perl does not always
# reside in the same place on different machines.
#--------------------------------------------------------------------------

set DIRS   = (/usr/bin  /usr/local/bin)
set PLFILE = /tmp/tmpplfile.$$

foreach dir ($DIRS)
  if (-e $dir/perl) then
    echo "#\!$dir/perl -w" > $PLFILE
    break
  else if ($dir == $DIRS[$#DIRS]) then
    echo "PERL NOT FOUND; SEE BEGINNING OF SCRIPT."
    exit
  endif
end

cat >> $PLFILE << "TO_THE_END_OF_THE_PERL_SCRIPT"

.
.
.

.
.
.

"TO_THE_END_OF_THE_PERL_SCRIPT"


===

Date: Fri, 10 Jan 2003 16:59:08 -0800
From: Belden Lyman <blyman at iii.com>
To: sfpug at sf.pm.org
Subject: Re: [sf-perl] [Fwd: [Fwd:perl scripting]]

M.Lewis wrote:

> What I've found is most perl scripts that you might download from one place or
> another will look for perl in only a couple of places. For instance
> /usr/bin/perl or /usr/local/bin/perl.
>
> I solved the problem with a symlink in /usr/local/bin (my perl lives in
> /usr/bin).
>
> Maybe too simple ?

Hey, it works. It's also described in 'perlrun' under ``Location of
Perl''.

The ``Description'' section of perlrun also presents such gems as:

     #!/bin/sh -- # -*- perl -*- -p
     eval 'exec perl -wS $0 ${1+"$@"}'
         if $running_under_some_shell;

and

     #!/usr/bin/env perl

which might be useful if symlinking isn't an option.

Belden

===

Date: Sat, 11 Jan 2003 00:11:13 -0800
To: sfpug at sf.pm.org
From: Rich Morin <rdm at cfcl.com>
Subject: Re: [sf-perl] [Fwd: [Fwd:perl scripting]]

I use this:

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

It has the advantage of using whichever version of perl comes first on
the PATH, just as if you had typed:

   % perl ...

-r

===


More information about the SanFrancisco-pm mailing list