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.