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
bengsig@orcenl.uucp (Bjorn Engsig) (11/21/88)
In article <5538@sdcrdcf.sm.unisys.com>, eggert@sea.sm.unisys.com (Paul Eggert) writes: > Mark Bartelt complained that in Berkeley Unix the shell command (X|Y|Z) ... > > 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? Oh no! We have the logical OR and AND as || and &&, and they are of course not pipe-symbols (they combine pipelines). Do you mean that (x|y|z) should never call z if y returned non-zero? Or should the all be called and the return codes simply logical OR'ed? In this case, what would the meaning be of, say 1|2|3 == 3, or 1|0|3 == 3? The SysV behaviour is the only acceptable one. -- Bjorn Engsig, ORACLE Europe \ / "Hofstaedter's Law: It always takes ..!uunet!mcvax!orcenl!bengsig X longer than you expect, even if you phone: +31 21 59 56 411 / \ take into account Hofstaedter's Law"
suitti@haddock.ima.isc.com (Steve Uitti) (11/23/88)
In article <5538@sdcrdcf.sm.unisys.com> eggert@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
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