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

拜拜、爱过 提交于 2019-11-27 09:10:09

问题


This question already has an answer here:

  • Pipe output and capture exit status in Bash 15 answers

I have a shell script in which I wrap a command (mvn clean install), to redirect the output to a logfile.

#!/bin/bash
...
mvn clean install $@ | tee $logfile
echo $? # Does not show the return code of mvn clean install

Now if mvn clean install fails with an error, I want my wrapper shell script also fail with that error. But since I'm piping all the output to tee, I cannot access the return code of mvn clean install, so when I access $? afterwards, it's always 0 (since tee successes).

I tried letting the command write the error output to a separate file and checking that afterwards, but the error output of mvn is always empty (seems like it only writes to stdout).

How can I preserve the return code of mvn clean install but still piping the output to a logfile?


回答1:


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

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



回答2:


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



回答3:


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.




回答4:


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


来源:https://stackoverflow.com/questions/6871859/piping-command-output-to-tee-but-also-save-exit-code-of-command

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!