「trueの時; echo y; done | trueは自然に死ぬが、while true; echo y | cat; done | yes'であるのはなぜですか?」

「trueの時; echo y; done | trueは自然に死ぬが、while true; echo y | cat; done | yes'であるのはなぜですか?」

タイトルの質問を明確にするために電子が死んだ理由を理解しています。後者が| 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| teeecho y | true

ループ本体にパイプがあると、信号に対するループの応答が変わるのはなぜですか?

答え1

には組み込まれているwhile true; do echo y; done | trueので、ループのパイプに書き込むサブシェルプロセスがあります。echoy\n

戻り値はパイプの読み取り端を閉じるため、書き込みの終わりtrueに書き込むと、aが書き込みSIGPIPEプロセスに渡されます。この場合、これはループを実行するサブシェルプロセスです。

ではパイプに書き込みますwhile true; do echo y | cat; done | true。通常組み込まれておらず、組み込まれていてもzshおよびksh以外のシェルでは、すべてのパイプラインコンポーネントが常に子プロセスで実行されます。catcat

したがって、ここでは実行中のプロセスのみが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によって殺された。

関連情報