A Unix irritation: pipeline status
Let's start with a Bourne shell irritation. Suppose you have a command sequence that looks like:
may-fail | grep ...
Further suppose that you want to know whether may-fail
actually
failed. In the normal Bourne shell, you're out of luck; the exit status
of a pipeline is the exit status of the last command, and grep
will
probably succeed no matter what happens to may-fail
. You're going
to need to use a temporary file instead of the pipeline or get very
creative.
It's tempting to blame the Bourne shell for this, but I think that its hands are at least partially forced by our old friend SIGPIPE. Consider this pipeline:
produce-lots | sed 10q
What's the exit status of this pipeline, assuming that produce-lots
would succeed if left alone?
Sed will exit successfully after writing ten lines. But this closes the
pipe, which means that produce-lots
gets either a SIGPIPE
signal
or an EPIPE
write error (if SIGPIPE
is being ignored). Unless
produce-lots
is specially coded, it is going to exit with some sort of
error status. If the Bourne shell only considered pipelines successful
if all of their commands succeeded, this sort of pipeline would fail,
much to people's surprise.
(The shell could consider pipeline commands that exited on SIGPIPE
to have succeeded, but that's an unreliable hack.)
Hence, the only reliable exit status is the exit status of the last command in the pipeline; everything else can wind up 'failing' when they have not in fact failed, it's just that the pipeline has shut down early.
|
|