Path: utzoo!attcan!uunet!olivea!apple!altos!megadon!clp From: maart@cs.vu.nl (Maarten Litmaath) Newsgroups: comp.unix Subject: Re: Nasty little shell syntax problem for a Wizard Message-ID: <2268@megadon.UUCP> Date: 21 Nov 90 00:02:33 GMT References: <2258@megadon.UUCP> Sender: clp@megadon.UUCP Reply-To: Maarten Litmaath Followup-To: comp.unix.shell Organization: VU Dept. of Computer Science, Amsterdam, The Netherlands Lines: 74 Approved: clp@megadon.UUCP Source-Info: From (or Sender) name not authenticated. )... )gcc 2>&1 | egrep -v "" ) )This has problems because the condition code that make seems to use is the )one from the egrep NOT the gcc. To obtain the exit status of a command in the middle of a pipeline you have to resort to things like this: a | b | (c; echo $? > /tmp/ecode$$) | d | e if [ `cat /tmp/ecode$$` != 0 ] ... If your OS supports named pipes (FIFOs) you could do this: TMPFIFO=/tmp/myfifo mknod $TMPFIFO p a | b | c > $TMPFIFO & < $TMPFIFO d | e wait $! echo "The exit status of c is $?" Still an ugly temp file hack. To avoid the temp file there's this gross construct: exec 3>&1 # Make file descriptor 3 a duplicate of stdout. # Below: make fd 4 a dup of the new stdout, i.e. the output stream # that's being captured. # Then execute each but the last component of the pipeline with # fd 3 closed; fd 4 is closed for each component but the one whose # exit status we want to capture. # The exit status is echoed to the remembered captured stdout. # Before the last component of the pipeline is started, its stdout # is connected to the original stdout, after which fd 3 can be # closed for this command as well. status=` exec 4>&1 a 4>&- 3>&- | b 4>&- 3>&- | (c 4>&-; echo $? >&4) 3>&- | d 4>&- 3>&- | e 4>&- >&3 3>&- ` exec 3>&- # We don't need it anymore. echo "The exit status of c is $status" In the case of a Makefile, however, we can easily avoid this whole mess: # Makefile for target target: dependencies (gcc 2>&1 || kill $$$$) | egrep -v "" Make sure the final part of the pipeline doesn't exit without having read all of the output of the first stage, else the latter might be killed with a SIGPIPE, as illustrated in the following example: foo: (cat /etc/termcap; kill $$$$) | true Furthermore to prevent the `egrep' from getting killed instead of the shell started by `make', you may want to use this instead: (gcc 2>&1 || kill $$$$) | (egrep -v ""; true) -- nreadwin@micrognosis.co.uk (Neil Readwin) on "snuff" films: "Seen one ? I was *in* one. They tortured me horribly and then killed me with a single shot in the back of the head ! Following total brain death I gave up acting and became a VMS hacker."