A Unix irritation: pipeline status

June 30, 2009

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.

Written on 30 June 2009.
« More on why users keep mailing specific people
Finding out when a command in a pipeline fails »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Jun 30 22:59:52 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.