Tzafrir Cohen <[EMAIL PROTECTED]> writes: > On Fri, Oct 24, 2003 at 10:47:22PM +0200, Oleg Goldshmidt wrote: > > Shlomi Fish <[EMAIL PROTECTED]> writes: > > > > > On Fri, 24 Oct 2003, Beni Cherniavsky wrote: > > > > > > > Shlomi Fish wrote on 2003-10-12: > > > > > > > > > I want that if one of the (first) components of the pipeline exits with an > > > > > error code, I'll know about it somehow. How? > > > > > > > > > info bash --index PIPESTATUS > > > > > > > > > > Cool thanks. > > > > Depending on your needs you may also use the -e option to the shell > > (should work for most Bourne shell and csh descendants), the option > > will make the shell exit if any of the commands in the pipeline fails. > > > > $ true | false | true > > $ echo $? > > 0 > > $ bash -e "true | false | true" > > true | false | true: true | false | true: No such file or directory > > $ echo $? > > 1 > > This is because you tried running a script from a file called > "true | false | true" > > However: > > $ set -e > $ true | false | true > $ echo $? > 0 > > So setting that doesn't make an error from the middle of a pipe show.
Hmm, this seems to be true. What is weird about it, is that it is supposed to do what I said. At least that is the way I used to read the bash documentation and also the make documentation (which is where I learned about -e from N years ago) - see below. Check http://www.gnu.org/manual/make-3.77/html_node/make_43.html that says "Here is the pattern rule to generate a file of dependencies (i.e., a makefile) called `name.d' from a C source file called `name.c': %.d: %.c $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \ | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \ [ -s $@ ] || rm -f $@' See section Defining and Redefining Pattern Rules, for information on defining pattern rules. The `-e' flag to the shell makes it exit immediately if the $(CC) command fails (exits with a nonzero status). Normally the shell exits with the status of the last command in the pipeline (sed in this case), so make would not notice a nonzero status from the compiler." Now, I created the following C file #include "foo.h" int main(void) { return 0; } (cpp should fail because there is no foo.h), and the following makefile: %.d: %.c $(SHELL) -ec '$(CC) -M $(CPPFLAGS) $< \ | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@' (I don't want foo.d removed if it contains nothing, otherwise it is identical to the example in the manual). Guess what: make does not "notice a nonzero status from the compiler" with or without -e. So I got curious, and added SHELL := csh to the makefile, and - lo and behold! - it worked (csh is a symbolic link to tcsh, and it works for both). Now, "man tcsh" says -e The shell exits if any invoked command terminates abnormally or yields a non-zero exit status. To compare, "man bash" says (for "set" builtin) -e Exit immediately if a simple command (see SHELL GRAMMAR above) exits with a non-zero status. The shell does not exit if the command that fails is part of an until or while loop, part of an if statement, part of a && or || list, or if the command's return value is being inverted via !. A trap on ERR, if set, is executed before the shell exits. Further RTFMing ("man bash" is at your service) uncovered that bash distinguishes between "simple commands", pipelines, and lists, and the -e applies to simple commands only, as per above. So it turns out that bash and tcsh behave differently. I apologize for my misleading post - it only applies to t?csh, it seems, not to bash (nor to zsh). I find it rather curious that the make documentation does not mention the difference. Now, I don't know what the rationale for bash behaviour is. It seems to me that the way tcsh behaves is pretty useful. -- Oleg Goldshmidt | [EMAIL PROTECTED] ================================================================= To unsubscribe, send mail to [EMAIL PROTECTED] with the word "unsubscribe" in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]