Is there a way to suppress pipe error, and just get the return code from make installer
?
An alternative solution to the other excellent answers already posted, if you don't want to run your whole command pipe in a subshell (e.g. you want to be able to set variables):
yes phrase | make installer || { ec=$?; [ $ec -eq 141 ] && true || (exit $ec); }
generic syntax:
cmd1 | cmd2 | cmd3 || { ec=$?; [ $ec -eq 141 ] && true || (exit $ec); }
This uses the exit
command in a subshell to preserve the original exit code from the command pipe intact, if it's not 141. Thus, it will have the intended effect if set -e
(set -o errexit
) is in effect along with set -o pipefail
.
We can use a function for cleaner code, which allows the use of return
instead of the exit
in a subshell trick:
handle_pipefails() {
# ignore exit code 141 from simple command pipes
# - use with: cmd1 | cmd2 || handle_pipefails $?
(( $1 == 141 )) && return 0
return $1
}
then use it or test it as:
yes | head -n 1 || handle_pipefails $?
echo "ec=$?"
then change the tested code from 141 to e.g. 999 in
the function, and see that ec was in fact captured as
141
An alternative, if you wanted to test the exit code of other commands involved in a more complex pipe, could be to test the whole PIPESTATUS:
handle_pipefails2() {
# ignore exit code 141 from more complex command pipes
# - use with: cmd1 | cmd2 | cmd3 || handle_pipefails2 "${PIPESTATUS[@]}"
for x in "$@"; do
(( $x == 141 )) || { (( $x > 0 )) && return $x; }
done
return 0
}
pipefail
? – Kusalananda Apr 27 '20 at 12:50set -e
has a wide variety of nonportable, contextually-dependent, generally surprising and hard-to-predict behavior; with details differing across POSIX-compliant shells, and within different versions of the same shell. Correspondingly, it makes code hard to audit for correctness, and is generally a Bad Idea. – Charles Duffy Apr 27 '20 at 23:58