我想执行Bash中长时间运行的命令,都捕获它的退出状态,并且发球它的输出。
所以我这样做:
command | tee out.txt
ST=$?
问题在于变量ST捕获了tee
而不是命令的退出状态。 我该如何解决?
请注意,命令运行时间长,将输出重定向到文件以供以后查看对于我来说不是一个好的解决方案。
#1楼
哑巴解决方案:通过命名管道(mkfifo)连接它们。 然后可以第二次运行该命令。
mkfifo pipe
tee out.txt < pipe &
command > pipe
echo $?
#2楼
有一个数组可以为您提供管道中每个命令的退出状态。
$ cat x| sed 's///'
cat: x: No such file or directory
$ echo $?
0
$ cat x| sed 's///'
cat: x: No such file or directory
$ echo ${PIPESTATUS[*]}
1 0
$ touch x
$ cat x| sed 's'
sed: 1: "s": substitute pattern can not be delimited by newline or backslash
$ echo ${PIPESTATUS[*]}
0 1
#3楼
有一个内部Bash变量$PIPESTATUS
; 它是一个数组,用于保存最后一个命令前台管道中每个命令的退出状态。
<command> | tee out.txt ; test ${PIPESTATUS[0]} -eq 0
或者也可以与其他shell(例如zsh)一起使用的另一种替代方法是启用pipefail:
set -o pipefail
...
第一个选项不工作zsh
由于一点点不同的语法。
#4楼
此解决方案无需使用bash特定功能或临时文件即可工作。 奖励:最后,退出状态实际上是退出状态,而不是文件中的某些字符串。
情况:
someprog | filter
要从退出状态someprog
和输出filter
。
这是我的解决方案:
((((someprog; echo $? >&3) | filter >&4) 3>&1) | (read xs; exit $xs)) 4>&1
echo $?