私は特にLinuxに興味がありますが、他のUnicesの答えも良いです。システムがバックグラウンドで開始されたプロセスにシグナルを送信する方法はありますか?つまり、スクリプトが起動したときにバックグラウンドにあるかどうかを知らせるために、私がキャプチャできる信号、またはBash/Perl/Pythonスクリプトまたは同様のスクリプトで確認できる信号がありますか?
ベストアンサー1
この文脈において、「背景」はいくつかの意味を持つことができる。
これはおそらく制御端末がないことを意味します。 (例えば、cron、systemd、またはinitから何かが始まります。)
バックグラウンドに入るだけでなく、getppid
親プロセス( )から隔離されると、親プロセスのpidは1になります。これは、制御端末の有無にかかわらず発生する可能性があります。
プロセスに制御端末がある場合は、フォアグラウンドまたはバックグラウンドにあります。
プロセスがフォアグラウンドにある場合、getpgrp
関数tcgetpgrp
は同じ値を返します(tcgetpgrpに制御端末のファイル記述子が割り当てられていると仮定します(例:2 = stderr)。
プロセスがバックグラウンドにある場合は、別の番号が返されgetpgrp
ます。tcgetpgrp
プロセスがフォアグラウンドにあり、停止している場合は、SIGSTOPまたはSIGTSTP信号のいずれかを受信します。 SIGSTOPはキャプチャできず、SIGTSTPをキャプチャしてもジョブは停止しません。
プロセスが停止状態で再開されると、SIGCONT信号を受信した後にフォアグラウンドにあるのか、バックグラウンドにあるのかを確認できます。
プロセスがバックグラウンドにあり、フォアグラウンドにインポートされた場合、信号は受信されないようですが、上記の確認は引き続き機能します。
プロセスがバックグラウンドにあり、入力または(おそらく)出力を試みると、キャプチャできるSIGTTINまたはSIGTTOU(それぞれ)を受け取ります。
上記は、LinuxおよびほとんどのUnixシステムをカバーするPOSIXシステムに当てはまります。
プログラムがパイプの中央にある場合、stdinとstdoutは制御端末ではありません(または、どちらかがパイプの両端にある場合は制御端末ではありません)。あるいは、stderrをリダイレクトすることもできます(ただし、可能性は低いです)。制御端末を開いて得ることができますが/dev/tty
(存在しない場合は失敗します)、移植性はありません。 (より良い方法があるかどうかはわかりません。)