ian@utcs.uucp (Ian F. Darwin) (12/09/85)
In article <1016@sdcsla.UUCP> west@sdcsla.UUCP (Larry West) writes: >However, I would like to point out that users have a habit >of naming programs "test", and of having "/bin" occur late >in their paths. This tends to cause confusion because the >problem (as usual) doesn't come up until that brief "test" >program has been forgotten. > >So, my suggestion is to always use "/bin/test" instead >of simply "test", or else use "[ ]". I know, fixing >the particular pathname of a program is a bad idea, but this >seems a fairly safe case (unless you plan to provide an >improved user interface to "test":-). No, no, no. Do not use absolute paths for test, mv, cp, or anything else. Least of all in shell files. Sure, once in a while a new user will make a program called `test' and get confused. Some people even do it twice (I did). Most people don't do it a third time. Note that the problem only comes up if you have your `test' program in your $HOME/bin (what you call your private bin directory) OR if you are in the same directory where you made that long-forgotten test program. On the other hand, if you post even a single shell file with /bin/test in it, your `error' will be repeated hundreds of times all over the world. Why is it an error? I call it an error because it violates the portability principle: UNIX uses the PATH environment variable to find programs, rather than making the user specify full path names for programs. This allows you to write your own. Why would anybody want to mv test out of /bin? Well, what if somebody decides that test is used so often that it belongs in the shell? Then you have to keep two versions of test around -- a fast one inside the shell, and a slow one for `erroneuos' shell files. Oh, you say that they already did this in some release of System V? My, what a surprise. I'm equally against the practice of putting /bin/rm, /bin/mv, etc into shell files. Please use rm, mv, etc, rather than the full paths. You don't know what might motivate me to have my own version of rm (indeed, you probably don't want to know what motivates me :=!). Please use the facilities that UNIX provides. Don't negate UNIX's wonderful generality for the benefit of a few nanoseconds. Ian Darwin Toronto, Canada
davel@dciem.UUCP (Dave Legg) (12/09/85)
> = Ian Darwin >> = Larry West In article <1019@utcs.uucp> ian@utcs.UUCP (Ian F. Darwin) writes: >In article <1016@sdcsla.UUCP> west@sdcsla.UUCP (Larry West) writes: >>However, I would like to point out that users have a habit >>of naming programs "test", and of having "/bin" occur late >>in their paths. ... >> >>So, my suggestion is to always use "/bin/test" instead >>of simply "test", or else use "[ ]". ... > >No, no, no. Do not use absolute paths for test, mv, cp, or >anything else. Least of all in shell files. > I can see both sides of this, I have run up against a user reporting a strange failure of a shell script that is installed for general use, and which usually works with no problem. The problem is that the user that finds such a problem is usually new and inexperienced, and it can take signifigant amounts of time to find that the whole problem is simply a name collision. One point not mentioned in the article I saw was that of the collision with a users program that had undesirable side effects. For example, if a user writes a program to delete files, and calls it some common system program name, then runs a script (which he might not even know is a script) which calls on that name. I have a suggestion. Set a shell variable to the absolute path of the program, i.e. TEST=/bin/test (or equivelent for other shells) and use $TEST in the shell program. This isolates the dependencies at the top of the script, making for easy changes. As for portability, if the changes are obvious and at the top, then any body getting a script from the net should be able to see what is necessary. Anybody recieving a script will normally at least scan it briefly to see what it does, especially if it fails. Although I can see that it is generally desirable to be as portable as possible, in shell scripts, I now normally fully qualify all proram names via the above convention. This is purely on the basis of experience with problems caused by unqualified program names in scripts. -- Dave Legg, DCIEM, Toronto, Ont. Canada. (416) 635-2065 {linus,ihnp4,uw-beaver,floyd}!utcsri!dciem!davel {allegra,ihnp4,linus,decvax}!utzoo!dciem!davel
geoff@utcs.uucp (Geoff Collyer) (12/09/85)
In article <1747@dciem.UUCP>, Dave Legg writes about Ian Darwin's
suggestion that absolute path names not be burned in to shell scripts,
and suggests that they be burned in at the top, in definitions like
TEST=/bin/test. (This is a particularly bad example since, as Ian
pointed out, test is a shell built-in in modern shells, but /bin/test is
not.)
Ian didn't mention our standard practice here: set PATH at the top of
the shell script (e.g. PATH=/bin:/usr/bin; export PATH). This is really
essential since otherwise an oddball PATH may result in a shell file
executing commands with the same name as standard commands but with
completely different effects. The author of a shell file usually
intends that the standard commands be used.
Yes, it does mean that your private versions of the standard commands
will not be found in shell files which set PATH to the standard
directories, but this is often just as well. Rather than rehash this
whole issue, I refer the interested reader to The UNIX* Programming
Environment by Brian Kernighan and Rob Pike, in which I believe this
topic is fairly thoroughly covered.
___
* According to p. 8 of the November 1985 issue of "$ echo", an
overpriced AT&T Marketing & Legal rag, I must, being a foreigner, utter
the magic mantra "Trademark of AT&T in the USA and other countries."
cc-06@ucbcory.BERKELEY.EDU (Ilya Goldberg) (12/10/85)
In article <1019@utcs.uucp> ian@utcs.UUCP (Ian F. Darwin) writes: >I'm equally against the practice of putting /bin/rm, /bin/mv, etc >into shell files. Please use rm, mv, etc, rather than the full paths. >You don't know what might motivate me to have my own version of rm >(indeed, you probably don't want to know what motivates me :=!). Please use >the facilities that UNIX provides. Don't negate UNIX's wonderful generality >for the benefit of a few nanoseconds. > >Ian Darwin >Toronto, Canada Ian, no one is trying to save cpu time by doing what they are doing. Just think of what would happen if the user doesn't have the right things in his/her path variable or no path at all! Also, I would love to try to break into a system kept secure by your shell scripts which do not contain absolute path names. I would do exactly what you suggest - substitute my own versions of rm, mv, etc so that when a set-u-id root shell script tries to execute one of those, UNIX will take the version in my directory. My version will perform whatever I want it to. including things you might not want me to. So, when writing programs/shell scripts which call other programs do include full path names, preferrably in a place where they are easily found and can be easily modified (e.g. ".h" files). Ilya (...!ucbvax!ilya)
chris@umcp-cs.UUCP (Chris Torek) (12/10/85)
[PATH=/foo:/bar:/baz; export PATH] In article <11193@ucbvax.BERKELEY.EDU> cc-06@ucbcory.BERKELEY.EDU (Ilya Goldberg) writes: > no one is trying to save cpu time by doing what they are doing. > Just think of what would happen if the user doesn't have the right > things in his/her path variable or no path at all! Then nothing works at all, so why worry about that case? > Also, I would love to try to break into a system kept secure by > your shell scripts which do not contain absolute path names. Who uses setuid shell scripts? (Actually, I have on one machine a shell script that is run privileged by a separate setuid C program, which verifies the user first; and the script is relatively careful.) > I would do exactly what you suggest - substitute my own versions of > rm, mv, etc so that when a set-u-id root shell script tries to > execute one of those, UNIX will take the version in my directory. Putting in full path names is not the solution---suppose I change $IFS? > So, when writing programs/shell scripts which call other programs > do include full path names, preferrably in a place where they are > easily found and can be easily modified (e.g. ".h" files). Include *paths*, not full path *names*. There is a difference. See `man execvp' and `man execlp'. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/10/85)
I have to disagree with Ian on this one. Because you never know what kind of weird $PATH people will be using, it is essential when writing shell scripts for use by others to FORCE the correct commands to be used in your shell script, in order to guarantee that the script does what you intended. The simplest way to do this is to just set PATH=whatever at the front of the script. Besides being less trouble than using absolute pathnames, this also handles problems like: Is "sort" in /bin or /usr/bin (or /usr/5bin)? The internals of a utility are subject to change. You can't even reasonably make the user responsible for looking inside utilities to see whether they will work in conjunction with his $PATH. As far as a user should be concerned, a utility should be a "black box" that does its job reliably and without fuss. If you're going to make a utility reliable, its internal operation should be protected against environmental factors except when they are a deliberate part of the interface. If someone has his own "rm" command (some of our users do), how do you know that it is suitable for use in your script to remove a link? The answer is, you don't.
mts@ms.UUCP (Martin Stanley) (12/10/85)
And just to add fuel to the fire: What about personal aliases conflicting with csh script commands. For example, many people around here alias rm to rm -i. This would break many csh scripts. The PATH solution given in geoff's article would not solve this problem. Of course, a *very* conscientious programmer could unalias every potentially conflicting name he uses in a script. :-) -- Martin Stanley Department of Computer Science University of Toronto Toronto, ON M5S 1A4 USENET: {decvax,ihnp4,linus,uw-beaver}!utcsri!utai!ms!mts CSNET: mts@toronto ARPANET: mts.toronto@csnet-rela
gmp@rayssd.UUCP (Gregory M. Paris) (12/11/85)
> No, no, no. Do not use absolute paths for test, mv, cp, or > anything else. Least of all in shell files. > > Sure, once in a while a new user will make a program called `test' > and get confused. Some people even do it twice (I did). Most > people don't do it a third time. As you mentioned, this kind of problem crops up not only with "test" but with many of the oft-used UNIX utilities. For those of us that support a user community of hundreds, even one or two "custom" utility problems per user can become quite a time consuming hassle. Just about any shell script can be broken with custom utilities, and I certainly don't expect every user to have the savvy to figure out which ones his/her new "rm" command is going to break (try rm -i -f). There's more than a speed advantage to including full pathnames, and only very minor portability problems associated with the practice. I'm not saying that you *must* or even *should* include full pathnames, but I disagree completely with your saying *never*! As a compromise, how about setting PATH at the beginning of the script? -- ++---------------------------------------------------------------------------++ || Greg Paris {allegra,linus,raybed2,ccice5,brunix}!rayssd!gmp || ++---------------------------------------------------------------------------++
rudy@wang.UUCP (Rudy Bazelmans x72609 ms 1989) (12/11/85)
> So, when writing programs/shell scripts which call other programs > do include full path names, preferrably in a place where they are easily > found and can be easily modified (e.g. ".h" files). > > Ilya (...!ucbvax!ilya) Users should NOT use full directory names in their scripts/programs UNLESS: 1) They specifically do not want the local version of a program. 2) They are writing setuid scripts (actually, this would be alright too if the script changed the path variable). If users use fullly qualified pathnames for programs, then administrators of systems would have to replace the standard programs with the new ones rather than allow both to be available.
jpn@teddy.UUCP (12/12/85)
>What about personal aliases conflicting with csh script commands. For >example, many people around here alias rm to rm -i. This would break >many csh scripts. The PATH solution given in geoff's article would not >solve this problem. Assuming you are talking about csh aliases, this does not come up in "sh" scripts (which was what the discussion was about). If you are writing csh scripts, then I hope your kernel also supports the "#! xxx" shell hack, or else the csh script startup times may be prohibatively long. If your kernel supports this, then use "#! /bin/csh -f" to avoid loading the user's .cshrc. >Of course, a *very* conscientious programmer could unalias every >potentially conflicting name he uses in a script. :-) How about "unalias *"?
henry@utzoo.UUCP (Henry Spencer) (12/13/85)
> What about personal aliases conflicting with csh script commands... > > Of course, a *very* conscientious programmer could unalias every > potentially conflicting name he uses in a script. :-) A conscientious programmer would never use csh to write scripts.
henry@utzoo.UUCP (Henry Spencer) (12/13/85)
> Also, I would love to try to break into a system kept secure by your > shell scripts which do not contain absolute path names. I would do exactly > what you suggest - substitute my own versions of rm, mv, etc... Wouldn't help, since all those shell scripts start with the magic line: PATH=/bin:/usr/bin ; export PATH which solves the problem without requiring hardwired path names everywhere. Also, it solves the problem for everything invoked by the shell script, rather than just for the shell script itself.
henry@utzoo.UUCP (Henry Spencer) (12/13/85)
> As a compromise, how about setting PATH at the beginning of the script?
This is not a compromise, it is the correct and complete solution. Don't
forget to do "export PATH".
tbray@mprvaxa.UUCP (Tim Bray) (12/13/85)
I am NOT a unix-wizard. But it seems elementary to me that all shell scripts should be as follows: #!/bin/sh PATH=/bin:/usr/bin:/usr/ucb # 'n maybe some more if test bletch .... mv foo rm bar etc.. That way you can't get bitten by (maybe intentional) name duplication, you will preserve the flexibility of path usage, and everything is hunky dory. This assumes that you can trust the contents of /bin:/usr/bin:/usr/ucb. If you want to use nonstandard commands as a privileged person, you should #$&*)$ well have them in a protected place - we use /opr. We had a secretary who created a little script called 'test' (dunno why) that printed out some guy's performance appraisal on her screen, and it turns out there were a FEW system scripts promiscuously using 'test' without protecting their paths - she was pretty upset for a while.
wcs@ho95e.UUCP (Bill.Stewart.4K435.x0705) (12/15/85)
In article <6223@utzoo.UUCP> henry@utzoo.UUCP (Henry Spencer) writes: >> Also, I would love to try to break into a system kept secure by your >> shell scripts which do not contain absolute path names. I would do exactly >> what you suggest - substitute my own versions of rm, mv, etc... > >Wouldn't help, since all those shell scripts start with the magic line: > > PATH=/bin:/usr/bin ; export PATH > >which solves the problem without requiring hardwired path names everywhere. >Also, it solves the problem for everything invoked by the shell script, >rather than just for the shell script itself. Henry and Ian are usually right :-), but ...... Actually, it has the potential for BREAKING almost everything invoked by the shell script, though not the shell script itself! If you do PATH=/bin:/usr/bin:$PATH: ; export PATH (perhaps with /usr/ucb/bin or /usr/lbin wedged in there) then the script can call other scripts that depend on the user's path. You do need to protect all the standard-location commands, but you should also allow the user's path to remain. (I once saw an in-house shell tutorial thatt showed a .profile with PATH=:/bin:/usr/bin:/4513/fred/bin: - the user had tried it out and wondered why lots of useful commands didn't work any more.) There are a few other fun commands to have local versions of. One of my users wrote a "sort", in Fortran. After he got it to compile, he decided to add some features, and "f77 sort.f" died with ugly errors. Seems the system V f77 compiler used "sort" to help with symbol tables, and his sort routine didn't take the same arguments as /bin/sort. -- # Bill Stewart, AT&T Bell Labs 2G-202, Holmdel NJ 1-201-949-0705 ihnp4!ho95c!wcs