bash/gnome-terminal のサブプロセスが終了しない (CentOS/RHEL)

bash/gnome-terminal のサブプロセスが終了しない (CentOS/RHEL)

今日、おそらく簡単に説明できるが、私にとってはまったく予想外のことを発見しました。私は CentOS (および動作が同じ RHEL) を実行しています。ターミナルで bash を開き、gedit などのサブプロセスを開始します。ウィンドウは問題なく開きます。「ps」を実行すると、gedit の親プロセスが bash であり、その親プロセスが gnome-terminal であることがわかります。次に bash を停止すると、すべての子プロセスも停止するはずです。しかし、gedit は実行し続け、親が 1 (init) に変更されました。

シェルを正常に停止せずに強制終了しようとしましたが、結果は同じでした。シェルの代わりにターミナルを終了しようとしましたが、それでも結果は同じでした。X ボタンをクリックしてターミナルを閉じると、gedit も閉じられます。

そのような動作は予想していませんでした。nohup で gedit を起動しても驚きませんが、nohup がなくても... なぜ gedit は動作し続けるのでしょうか?

誰かが何か明かしてくれて、そこで何が起こっているのか知っているかもしれません。よろしくお願いします!

答え1

gedit、gvim、google-chromeなどのプログラムは自動的にバックグラウンドに切り替わります。これにより、

gedit /home/msw/ul-answer

新しいウィンドウをマップして、シェル プロンプトを戻します。これは悪い設計選択ではなく、通常はこれを上書きするオプションがあります。 コマンドgedit -wと はgvim --nofork制御端末から切り離されず、シェル プロンプトを戻しません。

プログラムがバックグラウンドで実行されるには、フォークしてから親が終了します。これにより、入力するとすぐに、gedit の通常のインスタンスが init (PPID == 1) の子になります。

mplayer や calibre などの他のプログラムは、頻繁に入力されないか、デバッグ情報を制御端末にダンプするため、自動的にバックグラウンドに移行しません。

奇妙な点を追加:

これをテストして strace の出力などを確認するのに少し時間を費やしたところ、gedit は自動的にバックグラウンドに移行していないようです。gvim について述べたことは依然として有効であり、スリープする時間はとうに過ぎているので、今のところはそのままにしておきます。

答え2

ターミナルウィンドウを閉じると、カーネルはSIGHUPbash にシグナルを送ります。すると、bash は各ジョブに SIGHUP を送信し、SIGHUP で gedit を終了します。

exitまたはCtrl+と入力するかD、SIGKILL で強制終了して bash を終了すると、ターミナル エミュレーターは子プロセスが終了したことを認識し、ウィンドウを閉じます。Gedit は影響を受けません。

関連情報