Bug/misfeature in 4bsd /bin/sh

Steve Uitti suitti at haddock.ima.isc.com
Wed Nov 23 11:13:49 AEST 1988


In article <5538 at sdcrdcf.sm.unisys.com> eggert at sea.UUCP (Paul Eggert) writes:
>Mark Bartelt complained that in Berkeley Unix the shell command (X|Y|Z)
>nondeterministically yields the exit status of X, Y, or Z...
	[History & finger pointing part omitted.]
>Unfortunately, under either semantics, you can't tell whether all the commands
>in a pipeline succeed.  Instead, (X|Y|Z) should yield the logical OR of the
>exit statuses of X, Y, and Z.  Why didn't AT&T see this?

	Similar thoughts could be applied & back applied to scanf(3).
Scanf(3) returns a count of the number of things that went right,
though it can miss things.  Programs by convention return 0 for good
(no news is good news) and 1 for error.  Some programs return other
non zero numbers (like an error count, or error number, or a random
number that happened to be in register zero at the time).  Using the
logical OR of these numbers may reduce the information available.
Adding the exit statuses together yields the hope of adding the error
counts.  If the error counts were 1 each, as is typical, then one
might hope to get the number of commands that failed.  Also, some
commands will return -1, so that adding it to 1 will yield zero.  Some
wrap around checking should be done so that the exit status is always
nonzero if any were non zero.

	Since I'm an error checking fanatic (things should work), I
don't use scanf(3).  I also use cc(1) rather than sh(1) for
programming, for much the same reasons.  The type checking in cc(1) is
better.  There are types.  The code can be more readable.  Comments do
not slow the execution of production code.  Typically, the code
produced runs visually quicker, even on high speed machines.  The
language implemented by cc(1) is better documented.  Therefore, code
written using cc(1) can be more portable.  I know of several
nontrivial programs written in cc(1) that port to VMS, UNIX, MSDOS,
etc., but no nontrivial sh(1) programs.

	I see I've drifted from the topic at hand...

	To "fix" this problem with the shell, you need semantics which
allow you to find out how each of the programs in a pipeline did.
Perhaps an array of exit statuses could be maintained.

	Then we could add real types, with type checking.  Then pipe
types, where each program had a declared pipe type for input and
output.  Certain programs, called filters, could change piped data
types.  Non filter UNIX programs could be interactive, rather than
having the most brain damaged position dependent line noise syntax
imaginable (see mkfs(8)).  Not that this is really excusable for
filters.  Real people can't remember thousands of single digit options
for hundreds of two letter commands.  For better or worse, UNIX is
being put into the hands of novices.  Why?  Because we can.

	Stephen Uitti



More information about the Comp.unix.wizards mailing list