Jeff Damens <US.JD%CU20B@COLUMBIA.ARPA> (12/29/84)
> 1. What is the difference between > > sh < file > and > sh file With the "sh file" form, standard input can still be redirected (that is, standard input for any programs that are invoked by the shell; obviously the shell takes its input from file); the "sh < file" form doesn't allow input redirection. > 2. Why begin a shell script with > > #!/bin/sh > or > #!/bin/csh This tells the C shell which shell is supposed to interpret the shell script. It's necessary because the syntax of shell commands is different in the two shells; I think /bin/sh is used by default. However, if the script starts with a # and doesn't have the ! construct, the C shell is used Jeff Damens, Systems Integration Group, Columbia U. -------
chris@umcp-cs.UUCP (Chris Torek) (12/29/84)
> What is the difference between "sh < file" and "sh file" The first way keeps the script from reading anything else from its input. Consider the script while read word do echo $word | sed s/foo/bar/ done If run as ``sh zip'', it will read from your terminal, replacing ``foo'' with ``bar''. If run as ``sh < zip'', it will exit right away, since after reading the script, there's no input left. > Why begin a shell script with "#!/bin/sh" or "#!/bin/csh" Under 4BSD, at least, this makes the program exec()able (assuming that you have execute permission for that file). That is, the kernel can start this program, even though it's not machine code; the kernel will invoke the named program after fiddling arguments a bit. In fact, the script #! /bin/mv will rename itself! Place it in a file called ``zap'', and type ``zap zup'', and now you have a shell script called ``zup''. Your shell tried to exec() the program with the argument "zup". This succeeded, but actually ran /bin/mv with the arguments "zip" "zup". You can make self-removing scripts: #! /bin/rm Or self-printing scripts: #! /bin/awk NR > 1 { print } text... This last one works because the kernel is willing to do more than insert the filename in the argument list: it will insert one (and only one) optional argument. Normally, this is used for things like the ``-f'' option to the C shell (``fast'', don't read .cshrc's), but it works well enough for awk too. #! is described (though not completely) in man 2 execve in 4.2BSD. -- (This line accidently left nonblank.) In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (301) 454-7690 UUCP: {seismo,allegra,brl-bmd}!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@maryland
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (12/29/84)
> > 2. Why begin a shell script with > > > > #!/bin/sh > > or > > #!/bin/csh > > This tells the C shell which shell is supposed to interpret the > shell script. It's necessary because the syntax of shell > commands is different in the two shells; I think /bin/sh is used > by default. However, if the script starts with a # and doesn't > have the ! construct, the C shell is used Let's get this right, please. Recent BSD kernels understand the "#!" as a "magic number" and exec() succeeds in executing such a file, feeding it to the specified interpeter (which need not be one of the "shells"). Only if an attempt to exec() fails will the shell decide that it's a shell script and interpret it directly. It is extremely unfortunate that the Cshell thinks that # is not found in Bourne shell scripts; apart from the #! line, practically all of my Bourne shell scripts start with a # comment describing the function. The full story of which shell will run your script was discussed several months ago and is too gross to repeat. Suffice it to say, indicate with #!<shellpath> which shell you want and persuade your Cshell to interpret #! lines if your kernel doesn't.
david@ukma.UUCP (David Herron, NPR Lover) (12/31/84)
The "#!" form has other uses as well. Please peruse our phones command. #! /bin/grep ^[^#] The phone numbers to dial to reach the VAX-11/750 are: ttyh8 257-1474 ttyh9 257-5627 ttyha 257-1361 tty02 257-1353 tty04 257-1232 The number for room 907 is: 257-4244 (Sorry, should this be in net.sources?) One day I happened to notice in the kernal where this was being interpreted, and noticed that it was capable of handling ONE argument. So......... David Herron
jerryp@tektools.UUCP (Jerry Peek) (01/06/85)
In article <450@ukma.UUCP> david@ukma.UUCP (David Herron, NPR Lover) writes: >The "#!" form has other uses as well. Please peruse our phones command. > > #! /bin/grep ^[^#] > The phone numbers to dial to reach the VAX-11/750 are: > > ttyh8 257-1474 . . This also works well with "more +2"... to make a self-contained help program that paginates itself (don't even bother flaming about "more", please): #! /usr/ucb/more +2 For help with UNIX, call the Tek UNIXhelp hotlines: 627-5245 or 629-1630. UNIX classes are available at Tek: Call 627-1602 for information. The "sysinfo" command will give you a menu of tektools system information. The commands: apropos topic lists commands relevant to the topic man command shows the manual for a command . . . . --Jerry Peek, UNIX Training Instructor, Tektronix, Inc. US Mail: MS 76-036, P.O. Box 500, Beaverton, OR 97077 uucp: {allegra,decvax,hplabs,ihnp4,ucbvax}!tektronix!tektools!jerryp CS,ARPAnet: jerryp%tektools@tektronix.csnet Phone: 503/627-1603
ed@mtxinu.UUCP (Ed Gould) (01/07/85)
> > 2. Why begin a shell script with > > > > #!/bin/sh > > or > > #!/bin/csh > > This tells the C shell which shell is supposed to interpret the > shell script. It's necessary because the syntax of shell > commands is different in the two shells; I think /bin/sh is used > by default. However, if the script starts with a # and doesn't > have the ! construct, the C shell is used On recent 4bsd systems (certainly 4.2, I believe 4.1 and don't remember before) this construct also allows the file to be handled by the kernel's exec() routine. The documented syntax is #! pathname arg where the space after the ! (exactly one space character, or perhaps either one space or one tab) is required, and there may be no more than one argument. (In reality, the space has never to my knowledge been required.) The advantages of directly-execable scripts are two-fold. First, it allows *any* interpreter to be specified for the rest of the file, not just a shell. Second, the set-uid and set-gid bits are honored. Voila! Set-uid shell scripts! -- Ed Gould mt Xinu, 739 Allston Way, Berkeley, CA 94710 USA {ucbvax,decvax}!mtxinu!ed +1 415 644 0146 (I'd rather not be parochial.)
henry@utzoo.UUCP (Henry Spencer) (01/09/85)
> The advantages of directly-execable scripts are two-fold. ... > ... Second, the set-uid and set-gid bits > are honored. Voila! Set-uid shell scripts! Of course, as we all (should) know, setuid shell scripts are terminally insecure. The shell is just too complex, and there are too many ways to subvert it into doing things that the author of a (setuid) shell script did not intend. There are things that will help, like being careful to standardize PATH and having your shell refuse to import a non-standard value of IFS, but those aren't the only problems. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
jim@mcvax.UUCP (Jim McKie) (01/10/85)
In article <240@mtxinu.UUCP> ed@mtxinu.UUCP (Ed Gould) writes: >The advantages of directly-execable scripts are two-fold. First, >it allows *any* interpreter to be specified for the rest of the >file, not just a shell. Second, the set-uid and set-gid bits >are honored. Voila! Set-uid shell scripts! Unless you've fixed your kernel, if you have setuid shell scripts you have a security hole. Don't send me mail asking what it is. Jim McKie mcvax!jim
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (01/10/85)
> Unless you've fixed your kernel, if you have setuid shell scripts you > have a security hole. Don't send me mail asking what it is. One should be careful for ANY security-related code to check for loopholes. This means, in C code, argc == 0, PATH=funny_places, signals in critical places, fd 0, 1, and/or 2 not opened, etc. For shell scripts, one should ALWAYS set PATH=wherever and if security-critical set IFS=standard_whitespace and catch traps.
hans@log-hb.UUCP (Hans Albertsson) (01/13/85)
In article <7173@brl-tgr.ARPA> gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) writes: >> Unless you've fixed your kernel, if you have setuid shell scripts you >> have a security hole. Don't send me mail asking what it is. > >One should be careful for ANY security-related code to check for >loopholes. This means, in C code, argc == 0, PATH=funny_places, >signals in critical places, fd 0, 1, and/or 2 not opened, etc. >For shell scripts, one should ALWAYS set PATH=wherever and if >security-critical set IFS=standard_whitespace and catch traps. Well, do all of that, and still do NOT use any set-uid shell scripts. I had the bug demonstrated privately, and believe me, you should NOT permit setuid shell scripts. Ever. Period. No amount of defensive programming helps. A fix may or may not be available at a later date, they tell me. I have NO idea how that will be distributed, if ever. Or by whom. I've got it, I think ( hope? ), but won't spill. -- Hans Albertsson, USENET/uucp: {decvax,philabs}!mcvax!enea!log-hb!hans Real World: TeleLOGIC AB, Box 1001, S-14901 Nynashamn,SWEDEN