ときにtrue終了し、パイプの読み出し側が閉じられているが、yes書き込み側に書き込みしようとし続けます。この状態は「壊れたパイプ」と呼ばれ、カーネルがにSIGPIPE信号を送信しyesます。yesこのシグナルに関して特別なことは何もしないので、殺されます。シグナルを無視した場合、そのwrite呼び出しはエラーコードで失敗しますEPIPE。これを行うプログラムは、EPIPE書き込みに気づいて停止するように準備する必要があります。そうしないと、無限ループに入ります。
その場合はstrace yes | true1を、あなたは両方の可能性のための準備カーネルを見ることができます:
write(1, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 4096) = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=17556, si_uid=1000} ---
+++ killed by SIGPIPE +++
straceデバッガAPIを介してイベントを監視しています。デバッガAPIは、最初にエラーで返されるシステムコールについて通知し、次に信号について通知します。yesただし、の観点からは、信号が最初に発生します。(技術的には、カーネルが制御をユーザー空間に戻した後、それ以上のマシン命令が実行される前にシグナルが配信されるためwrite、Cライブラリの「ラッパー」関数errnoはアプリケーションに設定して戻る機会を得ません。)
1悲しいことに、straceLinux固有です。ほとんどの最近のUnixには、似たようなことをするコマンドがありますが、多くの場合、名前が異なります。おそらく、syscall引数を完全にデコードしません。
yes | tee >(true) >/dev/nullteeすべてのライターが死ぬまで継続するので、期待どおりに動作しますtrue。そのため、終了しても完全に混乱することはありません。