/dev/stdinから読み込まれたコマンドがバックグラウンドで送信されたときに[[1] + Stopped]状態を取得するのはなぜですか?

/dev/stdinから読み込まれたコマンドがバックグラウンドで送信されたときに[[1] + Stopped]状態を取得するのはなぜですか?

次のコマンドを実行してみました。

  • cat
  • base64 /dev/stdin
  • md5sum /dev/stdin
  • tail /dev/stdin

私がこれを行うすべての場合:

^Z
$ bg
$ jobs

私が得た状態は[1]+ Stopped次のとおりです[1]+ Running

ただし、パイプから読み取ると、ジョブは実行中と見なされます。

mkfifo /tmp/fifo1

cat /tmp/fifo1
^Z
$ bg
$ jobs

# [1]+  Running                 tail /tmp/fifo1 &


/dev/stdin読み取りコマンドがStoppedバックグラウンドで送信されたと見なされるのはなぜですか?

答え1

これは意図的に設計されています。 POSIX ジョブ制御が設計された方法です。

POSIXジョブ制御には、複数のジョブ(プロセスグループに配置されたプロセスとして表示されます)に関連付けられているTTYデバイス(「制御TTY」)があります。一度に 1 つのプロセスグループはフォアグラウンドプロセスグループで、残りはバックグラウンドプロセスグループです。

バックグラウンド・プロセス・グループ内のプロセスが制御端末からデータを読み取ろうとすると、シグナルを受信して​​停止SIGTTINします。

SIGTTOUバックグラウンドプロセスグループが受信することもできます。書くターミナルに行きます。この動作が適用されるか、つまりバックグラウンドで書き込みが許可されるかどうかを制御するTTYフラグがあります。 (このフラグを設定または消去するコマンドインタフェースはstty tostop/ですstty -tostop。)

アイデアは、バックグラウンドプロセスがTTY入力を盗むことができれば本当に混乱することです。キーストロークはバックグラウンドプロセスにランダムに配布されます。 POSIXジョブ制御は、混乱を防ぐために、交通警察官のようにプロセスだけでなく、TTY入力(および可能であれば出力)も処理します。

関連情報