Ing*_*her 150 bash shell pipe sh tee
我有一个shell脚本,我在其中包装一个命令(mvn clean install),将输出重定向到日志文件.
#!/bin/bash
...
mvn clean install $@ | tee $logfile
echo $? # Does not show the return code of mvn clean install
Run Code Online (Sandbox Code Playgroud)
现在,如果mvn clean install
失败并出现错误,我希望我的包装器shell脚本也会因该错误而失败.但是因为我将所有输出都传递给tee,所以我无法访问返回代码mvn clean install
,所以当我$?
之后访问时,它总是0(因为tee成功).
我尝试让命令将错误输出写入单独的文件并在之后检查,但mvn的错误输出始终为空(看起来它只写入stdout).
如何保留返回代码mvn clean install
但仍然将输出传递给日志文件?
Juk*_*nen 194
您可以设置pipefail
shell选项选项以获取所需的行为.
从Bash参考手册:
除非
pipefail
启用该选项,否则管道的退出状态是管道中最后一个命令的退出状态(请参阅Set Builtin).如果pipefail
启用,则管道的返回状态是以非零状态退出的最后(最右侧)命令的值,如果所有命令都成功退出,则返回零.
例:
$ false | tee /dev/null ; echo $?
0
$ set -o pipefail
$ false | tee /dev/null ; echo $?
1
Run Code Online (Sandbox Code Playgroud)
要恢复原始管道设置:
$ set +o pipefail
Run Code Online (Sandbox Code Playgroud)
Fré*_*idi 143
由于您正在运行bash
,您可以使用其$ PIPESTATUS变量而不是$?
:
mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}
Run Code Online (Sandbox Code Playgroud)
Dem*_*nex 11
您可以运行mvn命令并缓存退出代码...我的示例使用"false"命令.
$ { false ; echo $? > /tmp/false.status ; } | tee $logfile
$ cat /tmp/false.status
1
Run Code Online (Sandbox Code Playgroud)
这样您就可以使用状态文件内容做出进一步的决定.
我现在很好奇是否有更有说服力的方法来实现这一目标.