我要实现的BASH set -o pipefail
在POSIX方式选项,以便它可以在不同的Linux / UNIX版本。 要解释一下,这个选项允许用户检查所有管道命令的成功执行。 启用这个选项命令cat app.log | grep 'ERROR'
cat app.log | grep 'ERROR'
,如果失败cat
失败,否则, cat
被抑制的错误。
于是,我找到了一个非常好的解决方案在这里: http://cfaj.ca/shell/cus-faq-2.html
run() {
j=1
while eval "\${pipestatus_$j+:} false"; do
unset pipestatus_$j
j=$(($j+1))
done
j=1 com= k=1 l=
for a; do
if [ "x$a" = 'x|' ]; then
com="$com { $l "'3>&-
echo "pipestatus_'$j'=$?" >&3
} 4>&- |'
j=$(($j+1)) l=
else
l="$l \"\$$k\""
fi
k=$(($k+1))
done
com="$com $l"' 3>&- >&4 4>&-
echo "pipestatus_'$j'=$?"'
exec 4>&1
eval "$(exec 3>&1; eval "$com")"
exec 4>&-
j=1
while eval "\${pipestatus_$j+:} false"; do
eval "[ \$pipestatus_$j -eq 0 ]" || return 1
j=$(($j+1))
done
return 0
}
上述run()
函数使得用户能够调用这样一种方式的管道命令:
run cmd1 \| cmd2 \| cmd3
如果其中一个命令失败,你得到它在$?
然而有,它不支持管道之间的命令分组的问题。 我希望能够调用是这样的:
run echo "test" ; grep "test" \| awk '{print}'
当我这样做,则调用失败。 我不能得到正确的修改,以支持命令的分组 - 剧本是我的bash技能有点太复杂...
有人能帮忙吗?
谢谢!