Зачем выходить из кода 141 с помощью команды grep -q?

Может кто-нибудь объяснить, почему я получаю код выхода 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 является ошибкой, но строка выше дает ноль, так что это должен быть успех, я бы сказал.

4 ответа

Решение

Это потому что grep -q выходит сразу с нулевым статусом, как только совпадение найдено. zfs команда все еще пишет в канал, но нет читателя (потому что grep вышел), поэтому он отправил SIGPIPE сигнал от ядра и выходит со статусом 141,

Другое распространенное место, где вы видите это поведение с head, например

$ seq 1 10000 | head -1
1

$ echo ${PIPESTATUS[@]}
141 0

В этом случае, head читать первую строку и завершается, который сгенерировал SIGPIPE сигнал и seq выход с 141,

Смотрите " Печально известный сигнал SIGPIPE" в Руководстве программиста Linux.

Я не знаком с zfs list, но я думаю, что он жалуется на закрытие стандартного вывода - grep -q выходит сразу, когда совпадение найдено, в отличие grep,

Другой вариант - не использовать канал, а использовать подстановку процесса:

grep -q tank <(список zfs)

Вы можете просто продолжать есть результат, например:

      command | { head -n1; cat >/dev/null; }
Другие вопросы по тегам