See 'return codes' from Commands Inside a Chain of Pipes (pipeline)
It can be hard to tell if everything went okay inside a chain of pipes since $?
will only report the return code from the final command in the chain.
Using a different variable ($PIPESTATUS
) the return codes of all the commands chained together can be found.
#!/bin/bash
# as long as the last command in the pipe chain exits 0, RC will be set to 0
(exit 1) | (exit 2) | (exit 3) | true
echo "Pipe chain RC : $?"
echo -e "\n# Try again, using PIPESTATUS afterwards to see all RCs"
(exit 1) | (exit 2) | (exit 3) | true
# array of exit codes from the pipe chain
echo "Full PIPESTATUS array : ${PIPESTATUS[@]}"
# uh oh, running a command has reset the array
echo "Post \"echo\" PIPESTATUS array: ${PIPESTATUS[@]}"
echo -e "\n# Try again, saving the PIPESTATUS"
(exit 1) | (exit 2) | (exit 3) | true
SAVESTATUS=("${PIPESTATUS[@]}") # make a copy of the array
# uh oh, running a command has reset the array
echo "Post \"SAVE\" PIPESTATUS array: ${PIPESTATUS[@]}"
# but the copy is safe
echo "Full SAVESTATUS array : ${SAVESTATUS[@]}"
echo "Post \"echo\" SAVESTATUS array: ${SAVESTATUS[@]}"
set -o pipefail
echo -e "\n# Try again, turn on the BASH option for pipefail"
(exit 1) | (exit 2) | (exit 3) | true | echo 'Full pipeline still runs'
echo "Pipe chain RC : $?"
Produces the following output:
Pipe chain RC : 0
# Try again, using PIPESTATUS afterwards to see all RCs
Full PIPESTATUS array : 1 2 3 0
Post "echo" PIPESTATUS array: 0
# Try again, saving the PIPESTATUS
Post "SAVE" PIPESTATUS array: 0
Full SAVESTATUS array : 1 2 3 0
Post "echo" SAVESTATUS array: 1 2 3 0
# Try again, turn on the BASH option for pipefail
Full pipeline still runs
Pipe chain RC : 3