[net.unix] Shell programming style -- a pl

guy@rlgvax.UUCP (Guy Harris) (03/06/84)

> The only safe form I know of (for forcing a shell script to be executed
> by "sh" and not "csh" - gh) across ALL systems is to write a script that
> begins with a space...

I believe beginning the script with a colon will also work.

For those of you who have tuned in late, all versions of the Bourne shell,
even the V7 one, treat the colon as a command which throws away its arguments
and returns an "exit status" of 0 (it sort of acts like a comment, but it will
parse the text after the colon as arguments to a command, so beware of shell
meta-characters), while the C shell treats it as a signal to run the script
with "/bin/sh".  We've used it on several occasions and it works fine.  The
4.xBSD Bourne shell, and some other Bourne shells on systems with "csh", treat
a script whose *first character* is "#" as something to be run by "csh"
(elsewhere, "#" is just a comment in some Bourne shells), so beginning a
script with "#" may fail for one of the three following reasons:

1) Your Bourne shell may think it flags the script as a C shell script;

2) Your Bourne shell may not know the C shell from Adam, but doesn't understand
that "#" introduces a comment;

3) You used the "#! /bin/sh" construct to force it to be executed by "/bin/sh",
but your system doesn't have the trick (originally concocted by an employee
of Bell Labs, by the way) of the "magic number" "#!" introducing an executable
file header which indicates the pathname of an interpreter to be used to
interpret the contents of the file.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

gwyn@brl-vgr.ARPA (Doug Gwyn ) (03/07/84)

I have come to regret trying to help the novices by suggesting a way to
get the right command interpreter to execute their shell scripts.  The
claim that has been repeated most is that if your script does not start
with a # character the Bourne shell will execute it is FALSE for the
4.2BSD Cshell.  Only under some circumstances does this happen.  We have
seen scripts staring with : get fed to csh, much to the annoyment of the
user.

My original suggestion, that Bourne shell scripts start with #!/bin/sh,
is completely correct for the following UNIX variants:
	4.2BSD
	4.2BSD with BRL UNIX System V emulation
	UNIX System III
	UNIX System V
If you have some other UNIX system, the interesting question is "why?".

donn@hp-dcd.UUCP (03/10/84)

Careful with #!;  If you are running csh on a USG UN*X system
(System III or V), #! doesn't work.  The line #!/bin/sh will then
be seen by csh (after the exec fails), treated as a comment, and
cause csh to assume that it's a csh script (csh assumes that a file
beginning with # is a csh script).  System III and V, but
not V7, sh treat anything after a # as a comment.  The only safe 
form I know of across ALL systems is to write a script that begins
with a space:

 #  This is a /bin/sh script
echo hi there

If you have #!, then Doug's proposal will work.

This applies definitely to 4.1 csh, etc; I havn't tested it against
4.2, but I suspect it still applies.

Donn Terry
hplabs!hp-dcd!donn

fair@dual.UUCP (Erik E. Fair) (03/11/84)

Correction, Doug: System III and System V do NOT implement #!/bin/sh.
This is found ONLY in 4BSD decescendants

	from one who is even now suffering System V,

	Erik E. Fair

	dual!fair@BERKELEY.ARPA
	{ihnp4,ucbvax,cbosgd,decwrl,amd70,fortune,zehntel}!dual!fair
	Dual Systems Corporation, Berkeley, California

guy@rlgvax.UUCP (Guy Harris) (03/11/84)

When Doug said that "#!/bin/sh" at the beginning of a shell file would force
the shell file to be executed on 4.2BSD, S3, and S5, I think he meant "S3 and
S5 which haven't hacked the Bourne shell Berkeley-style to run scripts which
begin with "#" with the C shell".  That hack (having the Bourne shell run
scripts that begin with "#" with the C shell, and having the C shell run
scripts that begin with ":" with the Bourne shell) was done *before* "#"
was allowed as a comment character in Bourne shell scripts.  Now that it
*is* allowed, that hack is based on an invalid assumption and should not
be implemented.  As such, any *sane* S3/S5 implementation of the Bourne
shell won't feed scripts to the C shell if the script begins with "#".
If you want to have a way to have scripts "select" the shell that they're
to be executed by, the best solution is to bite the bullet and implement
"#!".  It's only 236 bytes of code on the VAX (I've pulled the code
out and compiled it!), permits you to implement set-UID shell scripts, and
has been blessed - hell, it was *invented* - by Dennis Ritchie himself.

I know at least one commercial V7 micro-based system with the C shell
implemented the heuristic based on the rule "Bourne shell scripts do not
begin with '#', and C shell scripts do not begin with ':'", which was
true in V7.  It's *not* true in S3 or S5, so if anybody puts the C shell
into their USG system they will *break things* if they put that rule into
the Bourne shell.  There are Bourne shell scripts *distributed with S3 and
S5* which begin with "#", so don't even *think* about putting that heuristic
in!  If you need to put in some way to identify scripts as Bourne or C
shell scripts, *please* send your $600 or whatever it is to the University
of California, get a 4.xBSD tape, and implement "#!".

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

dave@utcsrgv.UUCP (Dave Sherman) (03/12/84)

~|  From: gwyn@brl-vgr.ARPA (Doug Gwyn )
~|  ...  is completely correct for the following UNIX variants:
~|  	4.2BSD
~|  	4.2BSD with BRL UNIX System V emulation
~|  	UNIX System III
~|  	UNIX System V
~|  If you have some other UNIX system, the interesting question is "why?".

Because v7 is simple, standard, portable, and runs on my 11/23.

Dave Sherman
The Law Society of Upper Canada
Toronto
-- 
 {allegra,cornell,decvax,ihnp4,linus,utzoo}!utcsrgv!dave

ka@hou3c.UUCP (Kenneth Almquist) (03/14/84)

> If you want to have a way to have scripts "select" the shell that they're
> to be executed by, the best solution is to bite the bullet and implement
> "#!".

No need to put it into the kernel, either.  It should be easy to hack it
into the shell.
					Kenneth Almquist