Bash SIGPIPE – How to Suppress SIGPIPE in Bash

bashpipe

I'm trying to execute following code:

set -euxo pipefail
yes phrase | make installer

Where Makefile uses phrase from stdin to create installer file. However, this commands ends in error code 141, which breaks my CI build.
This example can be simplified to:

yes | tee >(echo yo)

From what is see here: Pipe Fail (141) when piping output into tee — why? – this error means that pipe consumer just stopped consuming output – which is perfectly fine in my case.

Is there a way to suppress pipe error, and just get the return code from make installer?

Best Answer

A 141 exit code indicates that the process failed with SIGPIPE; this happens to yes when the pipe closes. To mask this for your CI, you need to mask the error using something like

(yes phrase ||:) | make installer

This will run yes phrase, and if it fails, run : which exits with code 0. This is safe enough since yes doesn’t have much cause to fail apart from being unable to write.

To debug pipe issues such as these, the best approach is to look at PIPESTATUS:

yes phrase | make installer || echo ${PIPESTATUS[@]}

This will show the exit codes for all parts of the pipe on failure. Those which fail with exit code 141 can then be handled appropriately. The generic handling pattern for a specific error code is

(command; ec=$?; if [ "$ec" -eq 141 ]; then exit 0; else exit "$ec"; fi)

(thanks Hauke Laging); this runs command, and exits with code 0 if command succeeds or if it exits with code 141. Other exit codes are reflected as-is.

Related Question