`| less`を含むバックグラウンドジョブが停止されていない他のジョブが実行されるのはなぜですか?

`| less`を含むバックグラウンドジョブが停止されていない他のジョブが実行されるのはなぜですか?
$ pdfgrep -R -i spark . | less &
$ pdfgrep -R -i spark . &

$ jobs
[3]-  Stopped                 pdfgrep -R -i spark . | less
[4]   Running                 pdfgrep -R -i spark . &
  1. なぜそれを持っているのは| less止まり、そうでないものは実行されていますか?

    停止したバックグラウンドジョブは標準入力から読み取られません。したがって、それは理由になることはできません。

  2. タスクをバックグラウンドに設定したのは、同じ端末セッションで別のタスクを実行できるためです。

    私がパイプを使用する理由lessは、他のことをしている間にstdoutへの出力がターミナルセッションの画面を乱すことを望まないからです。

    上記の2つの目標を達成する方法はありますか?ファイルの記憶、読み取り、削除には時間がかかるため、出力をファイルに保存するよりも出力をファイルに保存しない方が少し良いです。

ありがとうございます。

ベストアンサー1

何が起こっているのかを詳しく見てみましょうless

$ pdfgrep -R -i spark . | strace less &
[...]
open("/dev/tty", O_RDONLY|O_LARGEFILE)  = 3
ioctl(3, TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig -icanon -echo ...}) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGTTOU {si_signo=SIGTTOU, si_code=SI_KERNEL} ---
--- stopped by SIGTTOU ---

タスク制御は、バックグラウンドタスクのプロセスが制御端末で特定のタスクを実行することを制限する。

  • バックグラウンドプロセスが端末からデータを読み取ろうとすると、通常、SIGTTINプロセスを停止(一時停止)する信号が送信されます。

  • バックグラウンドプロセスが端末のパラメータを設定しようとすると、信号はそのプロセスにSIGTTOU送信され、通常プロセスも停止します。それがここで起こったことです。TCSETSW I/W制御。プログラムlessは、開始直後に、表示する項目があるかどうかを知る前に端末を生モードに切り替えようとします。

    これには妥当な理由があります。つまり、ネイティブモードがオンでエコーがオフになっているかのように、バックグラウンドジョブが端末を非同期的に変更したくありません。 (バックグラウンドプロセスは得る停止せずにioctlの端末引数を使用してくださいTCGETS。上記のリストを参照してください。 )

  • バックグラウンドプロセスが端末に書き込みを試み、端末にフラグが設定されている場合、tostop信号は端末に送信されますSIGTTOU

tostopフラグが設定されていない可能性があります(実行しstty -aて確認)。そうしないと、これらのバックグラウンドコマンドはpdfgrep -R -i spark . &端末設定を変更せず、試みると端末に書き込むことができます。

また、次のように書きました。

私がlessを使う理由は、他のことをしている間にstdoutに出力してターミナルセッション画面を乱すことを望まないからです。

lessプログラムは最終的に一度に1画面ずつ出力を端末に送信します。stty tostopbeforepdfgrep | less &またはbeforeを実行すると、pdfgrep &フォアグラウンドにある場合にのみ端末に出力されます。

おすすめ記事