[comp.bugs.4bsd] Bug/misfeature in 4bsd /bin/sh

mark@sickkids.UUCP (Mark Bartelt) (11/18/88)

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@sickkids.utoronto
416/598-6442                          INTERNET: mark@sickkids.toronto.edu

guy@auspex.UUCP (Guy Harris) (11/19/88)

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

...

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

...

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

...

>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?

Did you try this under V7? The Berkeley shell is, as I remember, pretty
much the V7 shell, with support for "#" comments added.  If it does the
wrong thing under V7, you may have made an incorrect assumption here,
namely that in the Good Old Days it did the right thing and Berkeley
gratuitously changed it and ripped the comment in question from the man
page.  It may, in fact, have been that AT&T *fixed* the behavior of the
shell and *added* the comment in question.  Blame where blame is due,
and all that....

>(Someone reports that even SunOS gets it right, despite being
>4bsd-derived.

Another incorrect assumption; SunOS cannot be described solely by the
term "4bsd-derived".  SunOS 3.0's Bourne shell and "make" were derived
from the System V Release 2 versions, and the Bourne shell has been an
S5 one ever since, which is why it gets it right.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/19/88)

In article <117@sickkids.UUCP> mark@sickkids.UUCP (Mark Bartelt) writes:
>Does anyone else consider this a somewhat obnoxious misfeature?

No, it's a bug.  Not even job control requires the behavior you report.

henry@utzoo.uucp (Henry Spencer) (11/20/88)

In article <117@sickkids.UUCP> mark@sickkids.UUCP (Mark Bartelt) writes:
>... 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?  ...

Almost certainly Berkeley didn't change it.  The problem is that the
Berkeley sh is an antique, so old that you can hear its joints creak
when you put any stress on it.  More modern shells (including the
SysV shell that many otherwise-BSD-derived commercial systems run)
get this (and other things) right.
-- 
Sendmail is a bug,             |     Henry Spencer at U of Toronto Zoology
not a feature.                 | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

eggert@sea.sm.unisys.com (Paul Eggert) (11/20/88)

Mark Bartelt complained that in Berkeley Unix the shell command (X|Y|Z)
nondeterministically yields the exit status of X, Y, or Z, whereas in AT&T Unix
(X|Y|Z) always yields the exit status of Z.  He wrote that the Berkeley Unix
folks had removed words from the man page, and asked why Berkeley "changed the
semantics of the shell in this somewhat rude way?"

I'm afraid Bartelt had his history backward.  Older Bourne shells have the
nondeterministic semantics; newer ones from AT&T are deterministic.  AT&T made
the change, not Berkeley.

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?

das@eplunix.UUCP (David Steffens) (11/21/88)

In article <117@sickkids.UUCP> mark@sickkids.UUCP (Mark Bartelt) says:
> All the non-Berkeley versions of UNIX I can get my hands on give:
>	3 2 3 1 2 1
> On the other hand, under 4.3bsd we're treated to the following:
>	1 1 2 1 2 1

In article <474@auspex.UUCP> guy@auspex.UUCP (Guy Harris) says:
> Did you try this under V7?  ...  If it does the wrong thing under V7,
> you may have made an incorrect assumption here ...
> It may, in fact, have been that AT&T *fixed* the behavior of the
> shell and *added* the comment in question.

Guy is correct -- an (almost) plain vanilla v7 /bin/sh gives:
	1 1 2 1 2 1

The system I used for testing is known as "v7m", an early release
of DEC's Ultrix-11.  The code is basically Bell v7 re-worked
to run on a non-splt I/D PDP11.  The /bin/sh binary is dated
5 May 1979 and derives from sources dated 12 Jan 1979.
-- 
{harvard,mit-eddie,think}!eplunix!das		David Allan Steffens
243 Charles St., Boston, MA 02114		Eaton-Peabody Laboratory
(617) 573-3748					Mass. Eye & Ear Infirmary

mark@sickkids.UUCP (Mark Bartelt) (12/03/88)

In article <117@sickkids.UUCP> mark@sickkids.UUCP (Mark Bartelt -- Hey!
That's me!) writes:

[  Complaints about the behaviour of the 4bsd /bin/sh, specifically
   the non-deterministic (or, at least, peculiar and hard to predict)
   exit status of a pipeline, followed by example of proper behaviour
   under other UNIXes, and a quote from the sh(1) man page ...  ]

>      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. ]

[  More flaming about the absurd/bizarre exit status that pipelines
   produce under 4bsd, followed by ...  ]

> Eh?  I notice also that the Berkeley folks have removed the above
> sentence from the sh(1) man page.

Guy Harris, Henry Spencer, and a couple other people corrected me
regarding the above incorrect factoid, pointing out that the 4bsd
Bourne shell is essentially the Seventh Edition shell, with minor
changes, and that the V7 shell exhibited the same problem.

The really amusing/annoying thing is that the sh(1) manual page,
describing the && and || operators, refers to the value returned
by a pipeline, as if that value ought to be a rationally arrived
at entity.

So I still consider it a bug.  As bengsig@orcenl.uucp (Bjorn Engsig)
writes:

> The SysV behaviour is the only acceptable one.

In a piece of e-mail (without a "Message-ID:", or even so much as a
"To:" line!  How did it even get *delivered* to me?), research!norman
(Norman Wilson) sums it all up rather nicely:

> Wrong; Berkeley didn't take it out of the manual page.  [...]  [T]he
> exit status of a pipeline is specified in neither the V7 man page nor
> the Vol 2 sh paper.  I wouldn't be surprised if the mysterious, broken
> behaviour of BSD sh was borrowed from V7 as well.  [...]  Berkeley's
> sin [...] is one of omission rather than commission.  Not like sendmail
> at all.

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