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

时间:2013-10-01 15:31:45

标签: linux bash freebsd

有人可以解释为什么我从下面得到退出代码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失败,但上面的行给出零,所以它应该是成功,我会说。

3 个答案:

答案 0 :(得分:47)

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

您看到此行为的另一个常见位置是head。 e.g。

$ seq 1 10000 | head -1
1

$ echo ${PIPESTATUS[@]}
141 0

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

请参阅Linux程序员指南中的“The Infamous SIGPIPE Signal”。

答案 1 :(得分:5)

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

答案 2 :(得分:0)

另一种选择是不使用管道,而使用进程替换:

grep -q tank <(zfs列表)