bash 管道命令输出到三通,但也保存命令的退出代码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6871859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Piping command output to tee but also save exit code of command
提问by Ingo Fischer
I have a shell script in which I wrap a command (mvn clean install), to redirect the output to a logfile.
我有一个 shell 脚本,我在其中包装了一个命令(mvn clean install),以将输出重定向到日志文件。
#!/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).
现在,如果mvn clean install
因错误而失败,我希望我的包装器 shell 脚本也因该错误而失败。但是由于我将所有输出通过管道传输到 tee,我无法访问 的返回代码mvn clean install
,因此当我$?
之后访问时,它始终为 0(因为 tee 成功)。
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).
我尝试让命令将错误输出写入一个单独的文件并在之后进行检查,但 mvn 的错误输出始终为空(似乎它只写入标准输出)。
How can I preserve the return code of mvn clean install
but still piping the output to a logfile?
如何保留返回代码mvn clean install
但仍将输出传输到日志文件?
采纳答案by Frédéric Hamidi
Since you're running bash
, you can use its $PIPESTATUSvariable instead of $?
:
由于您正在运行bash
,您可以使用它的$PIPESTATUS变量而不是$?
:
mvn clean install $@ | tee $logfile
echo ${PIPESTATUS[0]}
回答by Jukka Matilainen
You can set the pipefail
shell optionoption on to get the behavior you want.
您可以设置pipefail
shell 选项选项以获得您想要的行为。
From the Bash Reference Manual:
来自Bash 参考手册:
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). Ifpipefail
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.
管道的退出状态是管道中最后一个命令的退出状态,除非
pipefail
启用了该选项(请参阅Set Builtin)。如果pipefail
启用,管道的返回状态是以非零状态退出的最后一个(最右边)命令的值,如果所有命令都成功退出,则为零。
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
回答by Demosthenex
You could run the mvn command and cache the exit code... I use the "false" command for my example.
您可以运行 mvn 命令并缓存退出代码...我的示例使用“false”命令。
$ { 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.
我现在很好奇是否有更雄辩的方法来实现这一点。
回答by Karoly Horvath
Workaround (note: a perfer @Frederic's solution):
解决方法(注意:一个更好的@Frederic 解决方案):
f=`mktemp`
(mvn clean install $@; echo $?>$f) | tee $logfile
e=`cat $f` #error in variable e
rm $f