Reputation: 43
I am writing a BASH script and two of the things I need it to do is:
I am finding that these two objectives are clashing.
First of all, I am using the ts
command to timestamp log entries, e.g. <a command/subscript> 2>&1 | ts '%H:%M:%S ' >> log
. Note that I need all the lines output of any subscripts to be timestamped too. This works great... until I try to handle errors using exit codes.
Any command that fails (exits with a code of 1) is immediately followed with the ts
command which executes successfully (exits with a code of 0). This means that I am unable to use the exit codes of the commands to handle errors with the $?
environment variable because ts
is always the last command to run and always has an exit code of 0.
Here is the case statement I am using:
<command> 2>&1 | ts '%H:%M:%S ' >> log
case $? in
0)
echo "Success"
;;
*)
echo "Failure"
esac
Upvotes: 4
Views: 209
Reputation: 50750
When a foreground pipeline returns, bash saves exit status values of its components to an array variable named PIPESTATUS. In this case, you can use ${PIPESTATUS[0]}
(or just $PIPESTATUS
; as you're interested in the first component) instead of $?
to get <command>
's exit status value.
Proof of concept:
$ false | true | false | true
$ declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="1" [1]="0" [2]="1" [3]="0")
Upvotes: 2