すべてのプロセスが端末に印刷できるにもかかわらず、一部のプロセスはLinux端末のバックグラウンドで実行できないが、他のプロセスは実行できるのはなぜですか?

すべてのプロセスが端末に印刷できるにもかかわらず、一部のプロセスはLinux端末のバックグラウンドで実行できないが、他のプロセスは実行できるのはなぜですか?

UbuntuでLinuxターミナルを使用しています。

seq 100 1 | less &バックグラウンドで実行しようとしたときに停止します。

を使用するなど、バックグラウンドで実行するために他の方法も使用しましたが、ちょうど停止bg [jobnr]しました。

Job番号を探して書き留めましたがbg 1(1のとき)プロセスを確認してみると実行にならないですね。

man pi他の「マンページ」でも同じことが起こります。

ただし、pi 10000000バックグラウンドで実行でき、完了すると端末にパイ番号が印刷されます。

less以下は、バックグラウンドで実行できるかどうか、そうでない理由を確認するためのタスクです。オンラインで検索しても原因に関する情報は多くありませんでした。

どちらも端末に印刷しますが、一部のプロセスはバックグラウンドで実行されず、他のプロセスは実行されるのですか?

答え1

less制御端末との対話を試みているため、バックグラウンドで実行できなくなり、強制的に停止します。フォアグラウンドプロセスのみが端末からデータを読み取るか、端末設定を変更できます。

SIGTTOUバックグラウンドプロセスが端末設定を変更しようとすると、シグナルを受け取ります。端末からデータを読み取ろうとすると信号が届きますSIGTTIN。両方の信号を停止させます。プロセスが実行され続け、これらのシグナルを無視すると、そのシグナルを発生させた操作が失敗する可能性があるため、これはこの問題に対する解決策ではありません(たとえば、端末からの読み取りがエラーで失敗するなどEIO)。

メモ:

lessほとんどのエディタやシェルなどの他の対話型プログラムと同様に、制御端末がstdinまたはstderrであると仮定するのではなく、操作するためにcommand | less制御端末を直接開くという点でユニークです。/dev/tty

stty tostopバックグラウンドプログラムが試みるように端末を設定できます。書く制御端末の動作も停止しますが、これはどこでもデフォルト設定ではなく、それほど実用的ではありません。

答え2

なぜなら、ターミナルアクセスが必要だからです。

プロセスがバックグラウンドで実行されている場合、すべての端末入力はフォアグラウンドで実行されているプロセス(おそらくシェル)に送信されます。文字を読む必要があるときにバックグラウンドプロセスが文字を選択すると、一般的なフォアグラウンド操作が妨げられます。これがどこにあるのかを理解するには、バックグラウンドプロセスがその間に端末だけを読むことができる場合は、何が起こるのかを考えてください。

Process1: important data(bg)    you type      Process2: just a quiz-game (fg)
output                                        output
                                             
Do you want to quit(q) or                     How do you call a group of 5 
   continue (c)                                     music players?
                          <-      q

OK, quit, save data?              u     ->
                                  i     ->
                          <-      n
                                  t     -> 
Ok destroyed all data.            e     ->
                                  t     ->
                                 <enter>->           Wrong answer: uitet.

次のスクリプトを例として、これがどのように機能するかを確認できます。

#!/bin/bash

while read sentence ; do
        echo "$sentence"
        echo '----------------'
        head -1 /dev/tty
done

readSTDINの入力を正常に読み込みます。すべてのコンテンツをリダイレクトできます。これにより、head -1 /dev/tty端末から入力が強制されます。フォアグラウンドで実行すると、スクリプトはユーザーが提供する各入力に対して1行を提供します。

このスクリプトをバックグラウンドで実行すると、cat tst.sh | bash tst.sh &端末で明示的に入力が必要な時点で停止します。

関連情報