When I concatenate 2 or more shell command with pipe (|), I get only the status of last one.
For example: "*some-cmd | logger -t "some-cmd messages:"; echo $?*"
If "*some-cmd*" fail with status !=0 I get always status of last one, in this case 0
In my case if the first command fail, I must send a warning message
A more simple example is: "false | true"
I want get status 1, of first command (false), not 0 (true)
I have also try "*sh -e -c 'false || exit 2|true'; echo $?*" but I get always 0
How to I get first status and break the chains of pipes ?
Bash has a built-in array called PIPESTATUS (documented in man bash) containing exit statuses from *all* stages of the previous pipeline. With PIPESTATUS you can check how each individual pipeline stage terminated. Here's a toy example:
# Random good-for-nothing pipeline with exit codes 55, 44, 33, 22, 11 and 0: (exit 55;) | (exit 44;) | (exit 33;) | (exit 22;) | (exit 11) | :
# Inspecting and copying PIPESTATUS ... caution, this has a caveat: # You can expand PIPESTATUS only once per pipeline. Copy it if need be. pipestatus=("${PIPESTATUS[@]}")
# Now you can check how each pipeline stage terminated! for stage in "${!pipestatus[@]}"; do echo "Stage ${stage} exited with status ${pipestatus[stage]}." done
Output from the cycle above: Stage 0 exited with status 55. Stage 1 exited with status 44. Stage 2 exited with status 33. Stage 3 exited with status 22. Stage 4 exited with status 11. Stage 5 exited with status 0.
That's it. Enjoy! Andrej