タイトルの質問を明確にするために電子が死んだ理由を理解しています。後者が| cat
ループ本体にaを追加するためにこれを行わない理由は理解できません。
何か関係があるかもしれませんが、
while true; do echo y; done
これはすぐに死ぬ^C
が死ぬ。
while true; do echo y | cat; done
多くの場合^C
、1回以上の打撃が必要です。時には一度、時には2〜3回、それから^C
死ぬまでしばらく耐えなければならない時もある。
これらの動作はすべてbashとzshで発生しますが、この^C
動作はbashではあまり一般的ではないようです。
両方の動作にパイプを追加することに限定されませんcat
。または原因にもなります。ループ本体にはパイプがないようです。| dd
| tee
echo y | true
ループ本体にパイプがあると、信号に対するループの応答が変わるのはなぜですか?
答え1
には組み込まれているwhile true; do echo y; done | true
ので、ループのパイプに書き込むサブシェルプロセスがあります。echo
y\n
戻り値はパイプの読み取り端を閉じるため、書き込みの終わりtrue
に書き込むと、aが書き込みSIGPIPE
プロセスに渡されます。この場合、これはループを実行するサブシェルプロセスです。
ではパイプに書き込みますwhile true; do echo y | cat; done | true
。通常組み込まれておらず、組み込まれていてもzshおよびksh以外のシェルでは、すべてのパイプラインコンポーネントが常に子プロセスで実行されます。cat
cat
したがって、ここでは実行中のプロセスのみがcat
終了しますが、ランループのサブシェルプロセスは標準出力に書き込まれるとすぐに終了するより多くの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はサブシェルでそのコマンドを実行しません)。したがって、サブシェルパイプはtrue
終了し、kill -l
それが実行されたことを確認します。 SIGPIPEによって殺された。