誰かが以下から終了コード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は失敗ですが、上記の行はゼロを示しているため、成功するはずです。
これは、一致が見つかるとすぐにgrep -q
がゼロステータスですぐに終了するためです。 zfs
コマンドはまだパイプに書き込みを行っていますが、リーダーが存在しないため(grep
が終了したため)、カーネルからSIGPIPE
信号が送信されて終了します。ステータスは141
です。
この動作が見られるもう1つの一般的な場所は、head
です。例えば.
$ seq 1 10000 | head -1
1
$ echo ${PIPESTATUS[@]}
141 0
この場合、head
は最初の行を読み取って終了し、SIGPIPE
シグナルを生成し、seq
は141
で終了しました。
The Linux Programmer's Guideの「 The Infamous SIGPIPE Signal 」を参照してください。
私はzfs list
に精通していませんが、標準出力が閉じられていると文句を言います-grep
とは異なり、一致が見つかるとすぐにgrep -q
は終了します。
別のオプションは、パイプを使用せずに、プロセス置換を使用することです。
grep -q tank <(zfsリスト)
更新:括弧内で実行されるプロセスもsigpipeを受け取るため、同じことだと思います。