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.
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.
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
.
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.