另一种可能性,带有一些bash 风格,是打开pipefail 选项:
管道故障
如果设置,管道的返回值为
最后一个(最右边)的值
命令以非零退出
状态,或零,如果在所有命令
管道成功退出。这
默认情况下禁用该选项。
set -o pipefail
...
command 2>&1 | tee -a file.txt || echo "Command (or tee?) failed with status $?"
话虽如此,实现PIPESTATUS 功能的唯一方法是可移植的(例如,它也可以与POSIX sh 一起使用)有点复杂,即它需要一个临时文件将管道退出状态传播回父 shell 进程:
{ command 2>&1 ; echo $? >"/tmp/~pipestatus.$$" ; } | tee -a file.txt
if [ "`cat \"/tmp/~pipestatus.$$\"`" -ne 0 ] ; then
...
fi
或者,封装以供重用:
log2file() {
LOGFILE="$1" ; shift
{ "$@" 2>&1 ; echo $? >"/tmp/~pipestatus.$$" ; } | tee -a "$LOGFILE"
MYPIPESTATUS="`cat \"/tmp/~pipestatus.$$\"`"
rm -f "/tmp/~pipestatus.$$"
return $MYPIPESTATUS
}
log2file file.txt command param1 "param 2" || echo "Command failed with status $?"
或者,更笼统地说:
save_pipe_status() {
STATUS_ID="$1" ; shift
"$@"
echo $? >"/tmp/~pipestatus.$$.$STATUS_ID"
}
get_pipe_status() {
STATUS_ID="$1" ; shift
return `cat "/tmp/~pipestatus.$$.$STATUS_ID"`
}
save_pipe_status my_command_id ./command param1 "param 2" | tee -a file.txt
get_pipe_status my_command_id || echo "Command failed with status $?"
...
rm -f "/tmp/~pipestatus.$$."* # do this in a trap handler, too, to be really clean