Objective: Get the exit status codes of all commands executed in a foreground pipeline (for example ‘command1 | command2 | command3’).
Traditionally, the shell variable ‘$?
‘ is used to determine the exit status of the last executed command. So, in the case of multiple commands that are piped, ‘$?
‘ will only give the exit status code of the last command executed in the pipeline.
1 2 3 |
$ echo foo | grep -q bar $ echo $? 1 |
The above printout shows that the exit status of the grep
command is 1. This is expected, as grep
is unable to perform a match.
To get the exit status of all the commands in the pipeline, we can use the bash shell array variable called ‘PIPESTATUS
‘. Note that this is a bash internal variable and is not available in all shells.
So, to get the exit status of all the commands in the pipeline in bash shell, we can use the following syntax.
1 2 3 |
$ echo foo | grep -q bar $ echo ${PIPESTATUS[@]} 0 1 |
The ${PIPESTATUS[@]}
variable prints out the whole array. As you can see from the above output, the echo
command has an exit status code of 0 and the grep
command has an exit status code of 1. Alternatively, we can selectively printout the exit status codes of the commands we are interested in.
1 2 3 |
$ echo foo | grep -q bar $ echo "${PIPESTATUS[0]} ${PIPESTATUS[1]}" 0 1 |
$PIPESTATUS[0]
holds the exit status of the first command (in our case, it is the exit status of the echo
command) in the pipe, $PIPESTATUS[1]
the exit status of the second command, and so on.
To get just the exit status of the second command in the pipeline, we can use the following syntax.
1 2 3 |
$ false | true | (exit 50) $ echo ${PIPESTATUS[1]} 0 |
The above will printout the exit status of the command true, which is 0.
In zsh
shell, you can use the $pipestatus
variable to print the exit status codes of all commands in a pipeline.