On 07/11/2014 02:58 PM, Paul Eggert wrote: > On 07/08/2014 12:42 PM, Eric Blake wrote: >> It is unclear >> at this point whether POSIX would recommend that filter >> applications should_always_ exit with 0 status on pipe failure, >> or only do this for EPIPE write failures when SIGPIPE is ignored, >> or whether it should be optional behavior that must be explicitly >> enabled via a command-line option and/or system-wide environment >> variable. > > None of these options sound appealing, I'm afraid. The first two would > be an incompatible change to longstanding standard behavior. A > system-wide environment variable would be problematic for all the usual > reaosns. A command-line option would be a pain to use (what? I have to > modify all my shell scripts?).
Not all your scripts, only those scripts where you plan to use 'set -o pipefail'. > > Instead, how about this idea? Change the behavior of the shell so that > SIGPIPE is not ignored in a pipeline (except in the pipeline's last > member of course), even if it is ignored in the parent. This is also a > change to POSIX, but it's a relatively minor one. Or, if we want to be > conservative about it, we could make the new behavior depend on a new > shell option. Either way, this would solve the problem without having > to change grep, sed, etc. That's not quite right. Remember, the choice is between: sigpipe normal: foo | bar if foo dies from SIGPIPE, but 'set -o pipefail' is in effect, then the whole pipeline fails with status 141 (SIGPIPE killed a member of the pipeline). vs. sigpipe ignored: foo | bar foo will NOT get SIGPIPE, but instead gets EPIPE. If it treats the write error as fatal, and exits non-zero, then 'set -o pipefail' fails the whole pipeline. But if it treats the write error as the request to do an early non-fatal exit with status 0, then the whole pipeline can also have status 0. The idea is that if you are going to write code with 'set -o pipefail', you would do it like: set -o pipefail (trap '' PIPE; foo) | bar set +o pipefail where you explicitly ignore SIGPIPE (and force EPIPE write errors) on any element of the pipeline where you expect the right side of the pipe may exit early. > > We might also want to have a way to reenable traps in the shell when > they're disabled; that's been a longstanding problem even aside from > this SIGPIPE business. Yes, that would be nice to have. But it goes in the opposite direction of 'set -o pipefail', because re-enabling default SIGPIPE behavior causes processes to die with status 141. Or are you arguing that any shell that provides 'set -o pipefail' should ALSO provide a knob to explicitly treat death due to SIGPIPE as not impacting pipefail? At which point, then you DO want to re-enable rather than ignore SIGPIPE, and don't have to worry about what child processes do on EPIPE, but only what they do on SIGPIPE, where death by SIGPIPE is not fatal to the pipeline. Probably worth adding some of these thoughts to the Austin Group bug proposal. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature