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