nohupにもかかわらず端末を閉じるとChromeブラウザが終了するのはなぜですか?

nohupにもかかわらず端末を閉じるとChromeブラウザが終了するのはなぜですか?

この質問はかなり古く、まだ理由がわかりません。


2014年の元の質問:

[Gnome Terminal] タブで、次を実行します。

$ nohup chromium-browser &

ただし、ターミナルタブを閉じると終了chromium-browserします。nohup停止しないでください。ザイルズ説明する:

nohupとdisownはどちらもSIGHUPを抑制すると言うことができますが、その方法は異なります。 nohupはプログラムが最初にシグナルを無視するようにします(プログラムはそれを変更できます)。 nohup はまた、端末が閉じたときにカーネルが SIGHUP 信号を送信しないように、プログラムが端末を制御しないように準備しようとします。 disownは純粋にシェルの内側にあり、SIGHUPを送信せずにシェルを終了します。

それでは、nohupはChromeブラウザがSIGHUPを無視するようにしませんか?

私はEmacs(GUIモード)のような他の実行可能ファイルでこれを見たことがあります。しかし、xeyesではそうではありません。

質問が投稿されたとき、これは32ビットUbuntu 12.04で発生しました。


2015年に更新され、

google-chrome今インストールする代わりにUbuntu 14.04を実行していますchromium-browser。 Chromeブラウザで起こったのとまったく同じことがGoogle Chromeでも起こっています。nohup google-chrome 2>/dev/null &ターミナルタブを閉じたときに閉じることを防ぎません。/usr/bin/google-chromebashスクリプトへのリンク/opt/google/chrome/google-chromenohupBashスクリプトに適用するとうまくいかないのはなぜですか? Bashスクリプトでどのように機能させることができますか? Pythonスクリプトはどうですか?

ベストアンサー1

GNOMEターミナルウィンドウを閉じると、SIGHUP信号が実行中のシェルに送信されます。シェルは通常、作成されたことがわかっているすべてのプロセスグループ(開始プロセスグループを含むnohup)にSIGHUPを送信して終了します。その場合、シェルはbashユーザーが表示したプロセスグループにSIGHUP転送をスキップしますdisown

コマンドを実行すると、nohupSIGHUPは無視されますが、プロセスでそれを変更できます。プロセスのSIGHUP処理がデフォルトの場合、SIGHUPを受信するとプロセスは終了します。

Linuxは、実行中のプロセスのシグナル設定を確認するためのツールを提供します。

Chromeブラウザのシェルスクリプトはexecコンパイルされたアプリケーションで動作するため、対応するプロセスIDは変更されません。そのため、信号設定を表示するために少し実行して信号構成をnohup chromium-browser &見ました。/proc/$!/status

SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003

これは16進数です。これは、SIGHUP が捕捉されなかったか無視されたことを示します。 SIGPIPE(SigIgnのビット13)のみが無視されます。私は以下を追跡しましたパスワード:

// Setup signal-handling state: resanitize most signals, ignore SIGPIPE.
void SetupSignalHandlers() {
  // Sanitise our signal handling state. Signals that were ignored by our
  // parent will also be ignored by us. We also inherit our parent's sigmask.
  sigset_t empty_signal_set;
  CHECK(0 == sigemptyset(&empty_signal_set));
  CHECK(0 == sigprocmask(SIG_SETMASK, &empty_signal_set, NULL));

  struct sigaction sigact;
  memset(&sigact, 0, sizeof(sigact));
  sigact.sa_handler = SIG_DFL;
  static const int signals_to_reset[] =
      {SIGHUP, SIGINT, SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGSEGV,
       SIGALRM, SIGTERM, SIGCHLD, SIGBUS, SIGTRAP};  // SIGPIPE is set below.
  for (unsigned i = 0; i < arraysize(signals_to_reset); i++) {
    CHECK(0 == sigaction(signals_to_reset[i], &sigact, NULL));
  }

  // Always ignore SIGPIPE.  We check the return value of write().
  CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR);
}

これにもかかわらず、両親が無視する兆候は次のとおりです。いいえ無視されました。 SIGHUPはクロムを殺します。

解決策は@xx4hが指摘したように行うことです。つまり、bashを終了する必要がある場合は、プロセスグループにSIGHUPを送信しdisownないようにbashでコマンドを使用します。chromium-browserこれを行う関数を書くことができます。

mychromium () { /usr/bin/chromium-browser & disown $!; }

おすすめ記事