Prevent Exit When Receiving SIGPIPE with Pipefail Set
When a program that is part of a pipeline quits, it closes its stdin and stdout. Programs that produce the input for the quitted process may still try to write to its stdin. Since they cannot, they will receive a SIGPIPE from the kernel.
You can see this in action:
$ seq 1 10000 | head -1
1
$ echo "${PIPESTATUS[@]}"
141 0
Conventionally, an exit status
N
greater than128
indicates the program was terminated by signalN - 128
. SinceSIGPIPE
is signal13
,141 - 128 = 13
indicates your program was ended by a SIGPIPE.
When running scripts with set -o pipefail
, this will terminate the
script, however. A workaround is to check for exit code 141
and exit
the pipeline with 0
instead:
seq 1 10000 | head -1 || \
{ if [ "$(kill -l "$?")" = PIPE ]; then exit 0; else exit "$?"; fi; }