pipe道命令输出到tee,但也保存命令的退出代码

我有一个shell脚本,其中我包装一个命令(mvn干净安装),将输出redirect到日志文件。

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

现在,如果mvn clean install失败并出现错误,我希望我的包装shell脚本也失败并出现该错误。 但是因为我把所有的输出pipe道都连接起来了,所以当我访问$?时,我无法访问mvn clean install的返回码$? 之后,它总是0(因为发球成功)。

我试图让命令写错误输出到一个单独的文件,然后检查,但错误输出mvn总是空的(好像只写入标准输出)。

我怎样才能保持mvn clean install的返回码,但仍然输出到一个日志文件?

既然你正在运行bash ,你可以使用它的$ PIPESTATUSvariables而不是$?

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

你可以设置pipefail shell选项来获得你想要的行为。

从Bash参考手册 :

pipe道的退出状态是pipe道中最后一个命令的退出状态,除非pipefail选项已启用(请参阅Set Builtin )。 如果启用pipefail ,则pipe道的返回状态是以非零状态退出的最后一个(最右边的)命令的值,如果所有命令均成功退出,则为零。

例:

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

要恢复原始pipe道设置:

 $ set +o pipefail 

您可以运行mvn命令并caching退出代码…我使用“false”命令作为示例。

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

这样你可以使用状态文件的内容做出进一步的决定。

我现在很好奇,是否有一个更有说服力的方法来实现这一点。

解决方法(注意:perfer @ Frederic的解决scheme):

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