bug-bash
[Top][All Lists]
Advanced

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

Re: pipefail with SIGPIPE/EPIPE


From: Pádraig Brady
Subject: Re: pipefail with SIGPIPE/EPIPE
Date: Thu, 23 Mar 2017 08:50:45 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0

On 15/02/15 14:14, Pádraig Brady wrote:
> On 15/02/15 21:59, Daniel Colascione wrote:
>> On 02/15/2015 01:48 PM, Chet Ramey wrote:
>>> On 2/13/15 12:19 PM, Pádraig Brady wrote:
>>>> I was expecting bash to handle SIGPIPE specially here,
>>>> as in this context it's informational rather than an indication of error.
>>>
>>> I don't agree.  It's a fatal signal whose default disposition is to
>>> terminate a process, which is exactly what happens in your example.
>>
>> The purpose of pipefail is to make the shell indicate when something has
>> gone wrong anywhere in a pipeline. For most programs, SIGPIPE does not
>> indicate that something went wrong. Instead, SIGPIPE is expected
>> behavior. When pipefail spuriously reports expected behavior as an
>> error, Bash comes less useful.
> 
> Exactly. SIGPIPE is special. It indicates the pipe is closed.
> That may be due to something having gone wrong down the pipe,
> but if that's the case the status code will be that of the
> failing process down the pipe.
> If it's only SIGPIPE that's significant to the status,
> then we know it's only informational, in which case the status
> should be 0 to indicate things have gone as expected.
> 
> There are many cases of the pipe being legitimately closed early.
>   ... | head
>   ... | grep -m1 ...
>   etc.
> 
>>> You might consider trapping or ignoring SIGPIPE in situations where it
>>> might be an issue.
>>
>> If I were emperor of the world, I would make SIGPIPE's SIG_DFL action
>> terminate the process with exit status 0. But POSIX says we can't do
>> that. Even locally, I make my system do that without kernel surgery.
>> It's also not reasonable to modify every program that might be part of a
>> pipeline so that it exits successfully on EPIPE.
>>
>> Making Bash treat SIGPIPE death as success is the next best option.
> 
> Only SIG_IGN isn't reset on exec, in which case each process
> would be getting EPIPE on write(), which most don't (and don't need to)
> handle explicitly. bash handling the SIGPIPE specially seems
> like the best option to me too.

I was bitten by this again when combined with set -e.
I.E. this script doesn't finish:

#!/bin/bash
set -o errexit
set -o pipefail
yes | head -n1
echo finished

That makes the errexit and pipefail options decidedly less useful.
Looking at this the other way, does the current behavior help,
or would any existing code be depending on the current behavior
of treating SIGPIPE as an error, when it's really only a shortcut
informational mechanism.

thanks,
Pádraig




reply via email to

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