[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: |
Sun, 15 Feb 2015 22:14:53 +0000 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 |
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 be too.
thanks,
Pádraig.