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 $!; }

答え2

クロムが特別に見えますね。

nohup chromium-browser & disownこの場合は動作するはずです。また見なさい: https://stackoverflow.com/questions/11421810/nohup-doesnt-work-with-chromium

答え3

その場合、最大の問題は次のとおりですchromium-browsergoogle-chromechromium-browser いいえchromiumexecただし、これは最初に状態を初期化してからsを初期化するシェルラッパーですchromium

私のgoogle-chromeインストールには実際にはバイナリがあり、/opt/google/chrome内部ラッパーはデフォルト値や絶対パスなどの/usr/bin多くの環境を設定し、xdg-*それを正しいバイナリに置き換えるシェルスクリプトです。

この時点で、nohup下付き文字で呼び出されたスクリプトによって最初に無視された可能性があるすべてのシグナルは、ラッパースクリプトがそれを慎重に異なる順序で配置しない限り重要ではありません。(しかし実際にはそうではありません)cttyは継承されます。

file /usr/bin/chromium-browser私の考えはシェルスクリプトであることを確認したいと思います。その場合は、自分に合うように書き直してください。

こうするだけでも心が開いていたと言えますがgoogle-chrome 2>/dev/null &、それが私がスクリプトを変更した結果だったかどうか覚えていません。それは1年以上でした。

関連情報