为什么用grep -q退出代码141?

有人可以解释为什么我从下面得到退出代码141?

#!/usr/bin/bash set -o pipefail zfs list | grep tank echo a ${PIPESTATUS[@]} zfs list | grep -q tank echo b ${PIPESTATUS[@]} cat /etc/passwd | grep -q root echo c ${PIPESTATUS[@]} 

我明白了

 ... a 0 0 b 141 0 c 0 0 

从我的理解退出代码141是失败,但上面的行给零,所以它应该是成功,我会说。

这是因为一旦找到匹配项, grep -q立即以零状态退出。 zfs命令仍在写入管道,但没有读取器(因为grep已经退出),所以从内核发送一个SIGPIPE信号,并退出,状态为141

另一个常见的地方,你看到这种行为是head 。 例如

 $ seq 1 10000 | head -1 1 $ echo ${PIPESTATUS[@]} 141 0 

在这种情况下, head读取第一行,并终止产生一个SIGPIPE信号和seq退出141

请参阅“Linux程序员指南”中的“臭名昭着的SIGPIPE信号 ”。

我不熟悉zfs list ,但我猜它抱怨它的标准输出被关闭 – grep -q在找到匹配时立即退出,与grep不同。