I have two processes foo
and bar
, connected with a pipe:
$ foo | bar
bar
always exits 0; I'm interested in the exit code of foo
. Is there any way to get at it?
--
There are 3 common ways of doing this:
Pipefail
The first way is to set the pipefail
option (ksh
, zsh
or bash
). This is the simplest and what it does is basically set the exit status $?
to the exit code of the last program to exit non-zero (or zero if all exited successfully).
$ false | true; echo $?
0
$ set -o pipefail
$ false | true; echo $?
1
$PIPESTATUS
Bash also has an array variable called $PIPESTATUS
($pipestatus
in zsh
) which contains the exit status of all the programs in the last pipeline.
$ true | true; echo "${PIPESTATUS[@]}"
0 0
$ false | true; echo "${PIPESTATUS[@]}"
1 0
$ false | true; echo "${PIPESTATUS[0]}"
1
$ true | false; echo "${PIPESTATUS[@]}"
0 1
You can use the 3rd command example to get the specific value in the pipeline that you need.
Separate executions
This is the most unwieldy of the solutions. Run each command separately and capture the status
$ OUTPUT="$(echo foo)"
$ STATUS_ECHO="$?"
$ printf '%s' "$OUTPUT" | grep -iq "bar"
$ STATUS_GREP="$?"
$ echo "$STATUS_ECHO $STATUS_GREP"
0 1