Alex
Alex

Reputation: 43

How can I create timestamped logs and error handle in BASH at the same time?

I am writing a BASH script and two of the things I need it to do is:

  1. Provide a timestamped log file.
  2. Handle errors.

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

Answers (1)

oguz ismail
oguz ismail

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

Related Questions