2 shell questions before the new year

Chris Torek chris at umcp-cs.UUCP
Sat Dec 29 11:24:55 AEST 1984


> 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 at umcp-cs		ARPA:	chris at maryland



More information about the Comp.unix mailing list