Nasty little shell syntax problem for a Wizard

Maarten Litmaath maart at cs.vu.nl
Wed Nov 21 11:02:33 AEST 1990


)...
)gcc <parms> 2>&1 | egrep -v "<re>"
)
)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 <parms> 2>&1 || kill $$$$) | egrep -v "<re>"

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 <parms> 2>&1 || kill $$$$) | (egrep -v "<re>"; true)
--
nreadwin at 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."



More information about the Comp.unix mailing list