Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!apple!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.unix.questions Subject: Re: portability of non-shell scripts Keywords: portability Message-ID: <11083@jpl-devvax.JPL.NASA.GOV> Date: 16 Jan 91 23:48:33 GMT References: <1991Jan15.233523.18150@ux1.cso.uiuc.edu> <14869@smoke.brl.mil> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 53 In article <14869@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: : In article <1991Jan15.233523.18150@ux1.cso.uiuc.edu> phil@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@jpl-devvax.jpl.nasa.gov