Path: utzoo!attcan!uunet!husc6!bloom-beacon!spdcc!ima!haddock!suitti From: suitti@haddock.ima.isc.com (Steve Uitti) Newsgroups: comp.unix.wizards Subject: Re: Bug/misfeature in 4bsd /bin/sh Message-ID: <10858@haddock.ima.isc.com> Date: 23 Nov 88 01:13:49 GMT References: <117@sickkids.UUCP> <5538@sdcrdcf.sm.unisys.com> Reply-To: suitti@haddock.ima.isc.com (Steve Uitti) Organization: Interactive Systems, Boston Lines: 50 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