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

coc*_*mac 12 command-line bash scripts error-handling pipe

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

somecommad | grep --invert-match something
Run Code Online (Sandbox Code Playgroud)

如果失败,我希望能够有条件地运行不同的命令somecommand。这是我尝试过的:

somecommand | grep --invert-match something || {
    echo 'Oops'
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用(grep没有执行)。执行此操作的正确方法是什么?

coc*_*mac 15

@steeldriver在评论中提到可能PIPESTATUS有效。我尝试了一下,效果很好。这就是我所做的:

somecommand | grep --invert-match something
if [ "${PIPESTATUS[0]}" != "0" ]; then
    echo 'Oops'
fi
Run Code Online (Sandbox Code Playgroud)

它像以前一样运行命令,但随后我有一个if语句来查看PIPESTATUS数组。我只关心第一个元素,所以这就是我所查看的元素。我检查它失败了(如果退出代码不是0),并且它确实失败了,运行echo 'Oops'


mur*_*uru 9

另一种方法是使用pipefail选项,具体取决于所需的确切行为:

管道的退出状态是管道中最后一个命令的退出状态,除非pipefail启用该选项(请参阅设置内置)。如果pipefail启用,管道的返回状态是最后一个(最右边)以非零状态退出的命令的值,如果所有命令都成功退出,则返回零。

因此,如果您不在乎哪一个somecommand失败grep,只要其中一个失败了:

set -o pipefail
if ! somecommand | grep --invert-match something; then
    echo 'Oops'
fi
Run Code Online (Sandbox Code Playgroud)