web-dev-qa-db-fra.com

Pourquoi quitter le code 141 avec grep -q?

Quelqu'un peut-il expliquer pourquoi j'obtiens le code de sortie 141 ci-dessous?

#!/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[@]}

Je reçois

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

D'après ma compréhension, le code de sortie 141 est un échec, mais la ligne ci-dessus donne zéro, donc cela devrait être un succès, je dirais.

32

Ceci est dû au fait grep -q se ferme immédiatement avec un état zéro dès qu'une correspondance est trouvée. La commande zfs écrit toujours dans le canal, mais il n'y a pas de lecteur (parce que grep est sortie), elle reçoit donc un signal SIGPIPE du noyau et se ferme avec un statut de 141.

Un autre endroit courant où vous voyez ce comportement est avec head. par exemple.

$ seq 1 10000 | head -1
1

$ echo ${PIPESTATUS[@]}
141 0

Dans ce cas, head lit la première ligne et se termine, ce qui génère un signal SIGPIPE et seq quitte avec 141.

Voir " The Infamous SIGPIPE Signal " du Guide du programmeur Linux.

51
dogbane

Je ne connais pas zfs list, mais je suppose qu'il se plaint que sa sortie standard soit fermée - grep -q se ferme immédiatement lorsqu'une correspondance est trouvée, contrairement à grep.

5
volferine

Une autre option serait de ne pas utiliser de pipe, mais d'utiliser une substitution de processus:

grep -q tank <(liste zfs)

Mise à jour: je suppose que c'est la même chose, car le processus exécuté entre parenthèses recevra également sigpipe.

2