This question already has an answer here:

I'm running a script within a script, release.sh and caller.sh (caller.sh calls release.sh). Both are bash.

release.sh contains a bunch of conditions with 'exit 1' for errors.

caller.sh contains a line that goes "./release.sh", then a checks for the exit code of release.sh - if $? is greater than 0 then echo "release.sh screwed up" and exits.

        if [ $? -gt "0" ] ; then
            echo "release_manager exited with errors, please see the release log."
            exit 1
            echo "release manager is done." 

Recently I've decided to log release.sh, and so the line in caller.sh goes:

./release.sh 2>&1 | tee release.txt

Because of the pipe, $? is the exit code of 'tee release.txt' , which always comes out as 0, regardless of the previous command :-(

I have to check for release.sh errors and stop the caller from proceeding, but I also really need that log.

Is there a way to get the exit code of the command before last? Or a different way to log the release script in the same command?

I'm not really in charge of release.sh, I'd rather not change it.

marked as duplicate by Stéphane Chazelas bash Mar 2 '16 at 10:57

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.


Since you are using bash you can set in the script the option:

set -o pipefail

The pipeline's return status is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands exit successfully.

Alternatively, immediately after the piped command you can look at builtin variable value ${PIPESTATUS[0]} for the exit code of the first command in the pipe.

PIPESTATUS: An array variable containing a list of exit status values from the processes in the most-recently-executed foreground pipeline (which may contain only a single command).

  • I like the ${PIPESTATUS[0]}, cheers! – Nahshon paz Mar 2 '16 at 10:50
  • Note that pipefail is also in mksh, ksh93 and zsh. $PIPESTATUS is bash-specific but was inspired from zsh's similar $pipestatus array. – Stéphane Chazelas Mar 2 '16 at 10:53

May I suggest rewriting it like that:

./release.sh > release.txt 2>&1

and then

echo $?

would return the correct exit status

Not the answer you're looking for? Browse other questions tagged or ask your own question.