Bug/misfeature in 4bsd /bin/sh

Mark Bartelt mark at sickkids.UUCP
Fri Nov 18 02:37:42 AEST 1988


Given the following three trivial shell scripts ...

        x1            x2            x3
        --            --            --
                   sleep 10      sleep 20
      exit 1       exit 2        exit 3

... what should the following produce as output?

      x1 | x2 | x3 ; echo 123: $?
      x1 | x3 | x2 ; echo 132: $?
      x2 | x1 | x3 ; echo 213: $?
      x2 | x3 | x1 ; echo 231: $?
      x3 | x1 | x2 ; echo 312: $?
      x3 | x2 | x1 ; echo 321: $?

All the non-Berkeley versions of UNIX I can get my hands on give:

      123: 3
      132: 2
      213: 3
      231: 1
      312: 2
      321: 1

This is consistent with the man page for sh(1), where it says:

      The exit status of a pipeline is the exit status
      of the last command.  [ By which it's clear that
      they mean the last command in the list, not the
      last command to exit. ]

On the other hand, under 4.3bsd we're treated to the following:

      123: 1
      132: 1
      213: 2
      231: 1
      312: 2
      321: 1

Eh?  I notice also that the Berkeley folks have removed the above
sentence from the sh(1) man page.  The question I have, is this all
a bug or a misfeature?  Does anyone happen to know why they changed
the semantics of the shell in this somewhat rude way?  The example
above is both contrived and silly (not to mention useless, other
than to demonstrate the problem), but it's frequently the case that
one wants to do something like ...

	if cmd1|cmd2|cmd3; then
		some_command_list
	else
		some_other_command_list
	fi

Historically, one could count on the fact that the "if" would be
testing the exit status of cmd3.  No longer.  I'm not even sure
what the exit status of a pipeline *is* under 4bsd.  It's quite
definitely *not* what it is under System V, Ninth Edition, and
almost everything else.  (Someone reports that even SunOS gets
it right, despite being 4bsd-derived.  I don't have access to a
Sun, so I can't verify that.)  On the other hand, it's not the
exit status of the last command to *exit*, nor is it always that
of the first command to exit, either.  As far as I can tell, the
exit status of a pipeline is undefined under 4bsd.

Does anyone else consider this a somewhat obnoxious misfeature?

Mark Bartelt                          UUCP: {utzoo,decvax}!sickkids!mark
Hospital for Sick Children, Toronto   BITNET: mark at sickkids.utoronto
416/598-6442                          INTERNET: mark at sickkids.toronto.edu



More information about the Comp.unix.wizards mailing list