如何使用管道检查命令是否失败?

如何使用管道检查命令是否失败?

所以我有一个这样的脚本:

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启用,管道的返回状态是最后一个(最右边)以非零状态退出的命令的值,如果所有命令都成功退出,则返回零。

因此,如果您不关心哪个somecommandgrep哪个失败了,只要其中一个失败了:

set -o pipefail
if ! somecommand | grep --invert-match something; then
    echo 'Oops'
fi

相关内容