bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: EPIPE in standard utils ([issue41])


From: Paul Eggert
Subject: Re: EPIPE in standard utils ([issue41])
Date: 03 Mar 2003 15:46:34 -0800
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.3

Tom Lord <address@hidden> writes:

> In my opinion, it is incorrect for a shell utility (such as sed or any
> of the textutils) to respond to EPIPE for stdout (and, arguably, any
> other output file) by
> 
>       1) printing a message on stderr
>       2) exiting with non-0 status

(2) doesn't seem correct to me.  A program that does not do anything
special will get a SIGPIPE signal when it writes to a pipe with no
reader, and accordingly will die with a nonzero status.  We can't
reasonably expect every program to catch SIGPIPE and do something
non-default in this case.  So we have to expect that an ordinary
program will exit with nonzero status if it writes to a pipe that has
no reader.

For (2), though, it's good practice for the program to exit with the
"interrupted-by-SIGPIPE" status.  That is, a program should either not
bother to catch SIGPIPE -- in which case it will do the right thing --
or it should catch SIGPIPE, do whatever cleanup it needs to do, and
then kill itself with SIGPIPE -- in which case it will also exit with
the proper status.  Conversely, ordinarily a program should not catch
SIGPIPE, do cleanups, and then exit with status 1, since then its
caller won't be able to determine that the utility terminated due to a
pipe problem.

(1) is not the default behavior, since a program that is killed by
SIGPIPE doesn't write anything to stderr.  So it might make some sense
to recommend against (1) for ordinary GNU utilities, and I think GNU
coreutils does this already.  However, it may be too much to prohibit
(1) entirely; there may be some applications for which it makes more
sense to print an error message.

> Under /bin/sh, undesirable behavior results from (1) as when the 
> the following idiom is used:
> 
>       if test -z `sed ... | head -1` ; then
>           ...

I agree that "sed" shouldn't print anything here, since it's an
ordinary utility.  But are you sure it's "sed" that is printing the
message, and not the shell that invokes "sed"?  Some shells have that
problem.


> (2) is also problematic in a /bin/sh idiom such as:
> 
>       ( sed ..... && .... ) | head -1
> 

For "(sed A && B) | head -n1", it's common to not want to execute B if
"sed A" fails due to a pipe error.  So it makes sense for "sed" to
exit with nonzero status if it has a pipe error.

If we adopt the "good practice" suggested above, then sed's invoker
can determine whether sed failed due to a pipe error, or due to some
other reason.  For example:

    if sed ....; then
      echo "sed succeeded"
    else
      sedStatus=$?
      if [ 128 -lt $sedStatus ] && [ "X`kill -l $sedStatus`" = XPIPE ]; then
        echo "sed failed due to a pipe problem"
      else
        echo "sed failed for some other reason"
      fi
    fi




reply via email to

[Prev in Thread] Current Thread [Next in Thread]