Bash怎麼會是真的;做迴聲y;完成 |true
怎麼會是真的;做迴聲y;完成 |true會自行消亡,但
while true;做迴聲 y |貓;完成 |不是嗎?
為了清楚標題問題,我理解為什麼前者會死。我不明白為什麼後者不這樣做,只是為了將 a 添加
| cat
到循環體中。也可能相關,
while true; do echo y; done
當我這樣做時會立即死去
^C
,但是會殺人while true; do echo y | cat; done
經常需要打
^C
不止一次。有時一次有效,有時2或3次有效,有時我需要堅持^C
一段時間讓它死掉。這兩種行為都發生在 bash 和 zsh 中,儘管這種行為在 bash 中
^C
似乎更罕見。對於這兩種行為,這不僅限於將管道添加到
cat
.| dd
,| tee
, 等也會導致它們。甚至echo y | true
導致它。它似乎是循環體中存在任何管道。為什麼循環體中存在管道會改變循環對信號的響應?
在
while true; do echo y; done | true
, 因為echo
是內置的,所以你有一個子shell程序,它y\n
在循環中寫入管道。返回時
true
,該管道的讀取端關閉,因此寫入寫入端會導致將 aSIGPIPE
傳遞給寫入程序。在這裡,這是執行循環的子shell 程序。在
while true; do echo y | cat; done | true
中,它cat
寫入管道。cat
通常不是內置的,即使是在 zsh 和 ksh 以外的 shell 中,所有管道組件始終在子程序中執行。因此,這裡只有正在執行的程序
cat
死亡,而執行循環的子shell程序繼續執行更多cat
程序,這些程序一旦y\n
在其標準輸出上寫入就會死亡。在 ksh93/ksh2020 中,如果您這樣做:
$ builtin cat $ type cat cat is a shell builtin $ set -o pipefail $ while true; do echo y | cat; done | true; kill -l "$?" PIPE
這一次,
cat
是內置的並且確實在與循環相同的程序中執行(就像cat
第一條管道中最右邊的命令一樣,並且 ksh 不在子shell中執行那個命令),所以子shell管道true
確實退出並kill -l
確認它是被 SIGPIPE 殺死。