portability of non-shell scripts

Larry Wall lwall at jpl-devvax.JPL.NASA.GOV
Thu Jan 17 10:48:33 AEST 1991


In article <14869 at smoke.brl.mil> gwyn at smoke.brl.mil (Doug Gwyn) writes:
: In article <1991Jan15.233523.18150 at ux1.cso.uiuc.edu> phil at ux1.cso.uiuc.edu (Phil Howard KA9WGN) writes:
: >Is there no consitency to this?  Has anyone worked a general way to make
: >these script programs more portable so that they will run w/o having to
: >have the user do editing on them?
: 
: About the best I know of is to ALWAYS use #!/bin/sh and tell that shell
: what command to run, with what arguments.  If you set $PATH to a nice,
: fairly inclusive set of possible directories then the command should be
: found no matter which of the directories it resides in.

"Nice" and "fairly inclusive" are fairly incompatible in this context.  Any
fairly inclusive PATH is not going to be very nice.  Your only hope is to
avoid setting PATH at all and use the user's imported PATH.  (You might add
a few directories to the user's PATH, but they're likely to be useless.)

Now, another minor quibble.  On some systems, putting #!/bin/sh will force
it to run under csh rather than sh!  So you need to be really careful to
speak only "shell pidgin".  Yes, it's ghastly, but we were talking about
maximum portability, not some idyllic ideal.  And how are you going to
pass any arguments to the subprogram?  You can use $*, but then filenames
containing spaces won't be handled right.  csh and sh have incompatible ways
of quoting arguments.

Another problem with the #!/bin/sh approach is that it may be difficult
to specify the text of the other program without using a second file or
installing a here-document in the script, either of which can be a pain.
Of course, if your language is designed (like awk) such that you can avoid
single quotes and specify the program as one of the arguments, you can
pass the program as a single-quoted string--but not all languages are
amenable to this.  And it still forces sh to process the whole program
before execution.

Perl can do the single-quote trick, but the maximally portable shell bootstrap
makes use of a three-language hack, in sh, csh and perl.  It avoids making
the shell read the whole file, and goes like this:

    eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}'
    & eval 'exec perl -S $0 $argv:q'
	if 0;

Even this won't work on those (thankfully few) machines with a csh that mixes
up the meaning of && and || (shudder).  I gave up trying to be portable at
that point.  Human nature being what it is, most people will simply continue
to post scripts with first lines like:

	#!/users/calc101/freddie/.hidden/prog/bin/perl

Personally, I'd rather doctor the #! lines and avoid starting up the extra
shell process on every invocation.  Simplicity lurks in strange places.

Larry Wall
lwall at jpl-devvax.jpl.nasa.gov



More information about the Comp.unix.questions mailing list