web-dev-qa-db-ja.com

バックグラウンドジョブはどこに行きますか?

Gnome-terminalから、C-zでジョブを一時停止し、それをバックグラウンドに送信する機能を知っています。ターミナルを閉じてもプロセスは終了しません。仕事はどこから管理されているのですか、それとも失われていますか?

5
camilla.greer

バックグラウンドジョブは、誰かがシグナルを送信して停止するように指示するまで実行を続けます。それが死ぬかもしれないいくつかの方法があります:

  • 何らかの理由で端末が停止すると、端末は HUP信号 (モデムのハングアップのように「ハングアップ」)を内部で実行されているシェルに送信します(詳細正確には、 制御プロセス )および フォアグラウンドプロセスグループ のプロセスに-)。したがって、バックグラウンドで実行されているプログラムは影響を受けませんが…
  • シェルはそのHUP信号を受信すると、それをバックグラウンドジョブに伝播します。したがって、バックグラウンドプロセスがシグナルを無視していない場合、この時点で終了します。
  • プログラムが端末から消えた後に読み取りまたは書き込みを行おうとすると、読み取りまたは書き込みは入出力エラー(EIO)で失敗します。その後、プログラムは終了することを決定する場合があります。
  • もちろん、あなた(またはシステム管理者)はいつでもプログラムを強制終了することができます。

プログラムの実行を継続することが懸念される場合は、次のようにします。

  • プログラムが端末と対話する可能性がある場合は、 Screen または Tmux を使用して自由に切断して再接続できる仮想端末でプログラムを実行します。
  • プログラムを実行し続ける必要があり、対話型でない場合は、Nohupコマンド(Nohup myprogram --option somearg)でプログラムを開始します。これにより、シェルがSIGHUPを送信せず、標準入力を/dev/nullにリダイレクトし、標準出力をリダイレクトします。 Nohup.outというファイルの標準エラー。
  • すでにプログラムを開始していて、ターミナルを閉じたときにプログラムが終了したくない場合は、シェルに組み込みのdisownがあれば実行します。そうでない場合は、極端な偏見を持ってシェルを強制終了することで、シェルによるSIGHUPの伝播を回避できます(指定されたプロセスの終了トリガーをバイパスする、そのシェルからのkill -KILL $$)。
  • すでにプログラムを開始していて、別の端末に再接続したい場合は、いくつかの方法がありますが、100%信頼できるわけではありません。 実行中のプロセスの所有権を剥奪し、それを新しい画面シェルに関連付けるにはどうすればよいですか? およびリンクされた質問を参照してください。

適切な信号を送信することで、ジョブをさらに制御できます(たとえば、killコマンドを使用)。

あなたはこれを試すことができます:

  • 長時間実行されるコマンドを実行します(たとえば、出力からわかるように、プロセスが実行されていることをyes
  • 押す Ctrl + Z
  • プロセスpidを決定します:pgrep yes
  • 再開プロセス(bgまたはfgと同等):kill -CONT <PID>、 どこ <PID>は、前のステップで決定されたプロセスIDです。
2
Martin Vejmelka

を押すと Ctrl+Z プロセスをバックグラウンドに送信せず、スリープに設定します。 fgコマンド(フォアグラウンド)でウェイクアップできます。 Ctrl+ZSIGSTOP(19)シグナルをプロセスに送信します。

あなたはこれを証明することができます:

  • 2つの端子を開きます。そのうちの1つにこのコマンドyes runningを入力すると、ターミナルで「実行中」「実行中」「実行中」が繰り返し出力されます
  • でプロセスを停止します Ctrl-ZpsコマンドでPIDを探します。
  • 2番目の端末に次のように入力します:kill -19 the_previous_PID、「yes」プロセスでも同じ効果が得られることがわかります。

kill -lと入力すると、使用できるすべての信号のリストが表示されます。

0
FarK