![如何使用管道检查命令是否失败?](https://linux22.com/image/942056/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E7%AE%A1%E9%81%93%E6%A3%80%E6%9F%A5%E5%91%BD%E4%BB%A4%E6%98%AF%E5%90%A6%E5%A4%B1%E8%B4%A5%EF%BC%9F.png)
所以我有一个这样的脚本:
somecommad | grep --invert-match something
我希望能够在somecommand
失败时有条件地运行其他命令。以下是我尝试的:
somecommand | grep --invert-match something || {
echo 'Oops'
}
但那不起作用(grep
没有执行)。正确的做法是什么?
答案1
@steeldriver评论中提到这PIPESTATUS
可能有用。我试过了,效果很好。以下是我做的:
somecommand | grep --invert-match something
if [ "${PIPESTATUS[0]}" != "0" ]; then
echo 'Oops'
fi
它像以前一样运行命令,但随后我有一个if
语句来查看PIPESTATUS
数组。我只关心第一个元素,所以我查看的是第一个元素。我检查它是否失败(如果退出代码不是0
),如果它确实失败了,则运行echo 'Oops'
答案2
另一种方法是使用选项pipefail
:
管道的退出状态是管道中最后一个命令的退出状态,除非
pipefail
启用了该选项(请参阅内置集合)。如果pipefail
启用,管道的返回状态是最后一个(最右边)以非零状态退出的命令的值,如果所有命令都成功退出,则返回零。
因此,如果您不关心哪个somecommand
或grep
哪个失败了,只要其中一个失败了:
set -o pipefail
if ! somecommand | grep --invert-match something; then
echo 'Oops'
fi