7

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?

3

3 Answers 3

8

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.

6
  • 3
    And for the paranoid: ( yes; ec=$?; if [ "$ec" -eq 141 ]; then exit 0; else exit "$ec"; fi ) | make installer ;-) Apr 27, 2020 at 13:18
  • (yes ||:) | tee >(echo yo) still returns 141
    – carbolymer
    Apr 27, 2020 at 13:45
  • @carbolymer yes, it does; but does your make exit with code 141? Your tee exits with 141 because echo yo stops reading; does that really reflect what your build is doing? Apr 27, 2020 at 13:47
  • I think so. make at some point also stops reading and in the end I have 141
    – carbolymer
    Apr 27, 2020 at 13:49
  • 1
    If make stops reading, that will cause yes to fail with a SIGPIPE, not make. make will fail with a SIGPIPE if it can’t write to a pipe. Apr 27, 2020 at 13:50
1
( yes phrase ; exit 0 ) | make installer
2
  • 1
    does not make a difference, (yes ; exit 0) | tee >(echo yo) still returns 141
    – carbolymer
    Apr 27, 2020 at 13:43
  • @carbolymer That's not what happens on my system. Make sure the exit code does not come from make: ( yes phrase ; exit 0 ) | ( make installer ; echo "make exit code: ${?}") Apr 27, 2020 at 14:31
-1

After some digging, I've found this answer: https://stackoverflow.com/questions/22464786/ignoring-bash-pipefail-for-error-code-141#comment60412687_33026977 Basically, using:

set -euxo pipefail
yes phrase | make installer || (ec=$? ; if [ "$ec" -eq 141 ]; then exit 0; else exit "$ec"; fi)

just filters out SIGPIPE from return codes.

1
  • This will hide the real exit code for any other failure... Apr 27, 2020 at 13:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.