Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Piping command output to tee but also save exit code of command [duplicate]

Tags:

bash

shell

sh

pipe

tee

People also ask

How do you pipe a command output?

The > symbol is used to redirect output by taking the output from the command on the left and passing as input to the file on the right.

How do I capture an exit code?

To check the exit code we can simply print the $? special variable in bash. This variable will print the exit code of the last run command.

What is Bash Pipestatus?

Bash also has an array variable called $PIPESTATUS ( $pipestatus in zsh ) which contains the exit status of all the programs in the last pipeline.

What is tee command used for?

The tee command, used with a pipe, reads standard input, then writes the output of a program to standard output and simultaneously copies it into the specified file or files. Use the tee command to view your output immediately and at the same time, store it for future use.


You can set the pipefail shell option option on to get the behavior you want.

From the Bash Reference Manual:

The exit status of a pipeline is the exit status of the last command in the pipeline, unless the pipefail option is enabled (see The Set Builtin). If pipefail is enabled, 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.

Example:

$ false | tee /dev/null ; echo $?
0
$ set -o pipefail
$ false | tee /dev/null ; echo $?
1

To restore the original pipe setting:

$ set +o pipefail

Since you're running bash, you can use its $PIPESTATUS variable instead of $?:

mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}

You could run the mvn command and cache the exit code... I use the "false" command for my example.

$ { false ; echo $? > /tmp/false.status ; } | tee $logfile
$ cat /tmp/false.status
1

That way you can use the status file content to make further decisions.

I'm curious now whether there is a more eloquent way to accomplish this.


Workaround (note: a perfer @Frederic's solution):

f=`mktemp`
(mvn clean install $@; echo $?>$f) | tee $logfile
e=`cat $f` #error in variable e
rm $f