From: clewis@ferret.ocunix.on.ca (Chris Lewis)
Newsgroups: news.software.b,comp.unix.programmer,alt.folklore.computers
Subject: Re: inews in C - shell/awk scripts are unreliable!
Date: 7 Nov 92 05:37:09 GMT
Followup-To: news.software.b
Organization: Elegant Communications Inc., Ottawa, Canada

In article <1992Nov2.063450.28552@robohack.UUCP> woods@robohack.UUCP (Greg A. Woods) writes:
> [As an aside it is interesting to explain the logic behind this
> compromise.  Since SysV doesn't support the "#! interpreter" syntax,
> ISC (and perhaps AT&T) decided to modify csh such that it recognizes a
> ":" as the first character of a /bin/sh script, and thus "do the right
> thing".

Nope.  This vastly predates #!.  This dates back to when /bin/sh
didn't support "#" as a comment.  Ie: V6 days.  Csh has always
needed to tell the difference between csh and whatever /bin/sh was,
long before there was kernel support for #!, before BSD had Bourne
shell in fact.

Both /bin/sh and csh try to start scripts by exec'ing them.  If that
fails (no magic number), csh was designed to recognize that it
was to run the shell itself iff it found a "#" as the first character.
It would run /bin/sh if the first character wasn't "#".  Since the
V6 shell (which was what was in early BSDs instead of Bourne) had
a ":" comment, the convention then became to use ":" as the first line.
On the other hand, in the very early days, /bin/sh (V6 or V7 style) wasn't
csh-aware, so wouldn't start csh without "help".  I remember seeing
the source in BSD 4.1 that implemented csh awareness in /bin/sh.

Prior to that, sh thought it was supposed to run anything that
wasn't an executable binary, and only csh knew that there was
another shell that could be necessary.  But it only implemented one:
/bin/sh.

All cshs know that scripts must start with "#" to be executed
by the C shell (thru implicit invocation).  And will run /bin/sh
otherwise.  That is, if csh gets to see it - #! kernel support
means that csh is invoked via the kernel on the script in an explicit
fashion.

A blank line is sufficient with most systems.  However, /bin/sh isn't
always what you want (Ultrix /bin/sh being a case in point).

The #! was an attempt by BSD to simplify and generalize multiple
interpreter support and get to play games with setuid.  I think that
stuff was introduced in BSD 4.2.  Unfortunately, they didn't do a complete job.
Even worse, AT&T and Xenix frequently botched it.  So the result
is a confusing mismash.  But ":" still works everywhere to invoke
/bin/sh.  Which is all you need, except for the unfortunate situations
when /bin/sh isn't what you really want (as in Ultrix where sh5
is what you usually want).

While leading your script with an unadorned ":" will in very rare
situations result in the wrong shell, more complicated sexy schemes
(like your shell header) are known to fail in a number of common
environments.  Like some Xenix csh getting && and || backwards.
So, if you want /bin/sh, it's best to use a simple ":", and fix
it with #! in the rare occasions it doesn't work.

Where this may cause grief is when shells other than /bin/sh or
csh don't implement this properly.  They should be fixed.
-- 
Chris Lewis; clewis@ferret.ocunix.on.ca; Phone: Canada 613 832-0541
Psroff 3.0 info: psroff-request@ferret.ocunix.on.ca
Ferret list: ferret-request@ferret.ocunix.on.ca
Xref: sparky news.software.b:3326 news.software.readers:2134