Зачем выходить из кода 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; }