Chrome

儘管 nohup 關閉終端,為什麼鉻瀏覽器會被殺死?

  • March 1, 2016

這個問題很老了,我仍然不清楚為什麼。


2014年的原始問題:

在 Gnome 終端選項卡中,我跑了

$ nohup chromium-browser &

但是當我關閉終端選項卡時,chromium-browser也會退出。不nohup應該阻止嗎?吉爾斯說:

nohup 和 disown 都可以說是抑制 SIGHUP,但方式不同。nohup 使程序最初忽略信號(程序可能會改變這一點)。nohup 還試圖安排程序沒有控制終端,這樣當終端關閉時,核心就不會發送 SIGHUP 信號。disown 純粹是在 shell 內部;它會導致 shell 在終止時不發送 SIGHUP。

那麼 nohup 不會讓 chromium-browser 忽略 SIGHUP 嗎?

我也在其他執行檔上看到了這一點,例如 Emacs(GUI 模式)。但不是在 xeyes 上。

發布問題時,這發生在 32 位 Ubuntu 12.04 上。


2015年更新,

現在我正在執行 Ubuntu 14.04,google-chrome而不是chromium-browser安裝。以前發生在 chromium-browser 上的事情現在也發生在 google-chrome 上。nohup google-chrome 2>/dev/null &當終端選項卡關閉時,它不會被關閉。/usr/bin/google-chrome是一個 bash 腳本的連結/opt/google/chrome/google-chrome。為什麼nohup應用於 bash 腳本不起作用?我們如何使它在 bash 腳本上工作?Python 腳本呢?

當您關閉 GNOME 終端視窗時,會向它正在執行的 shell 發送一個 SIGHUP。shell 通常會向它知道它創建的每個程序組發送一個 SIGHUP——即使是那些以它開頭的程序組nohup——然後退出。如果 shell 是bash,它將跳過向使用者標記的任何程序組發送 SIGHUP disown

執行命令nohup使其忽略 SIGHUP,但該過程可以改變這一點。當程序的 SIGHUP 處置是預設配置時,如果它收到 SIGHUP,則該程序將被終止。

Linux 提供了一些工具來檢查正在執行的程序的信號設置。

chromium-browser shell 腳本執行exec編譯後的應用程序,因此它的程序 ID 保持不變。所以要查看它的信號設置,我跑了nohup chromium-browser &,然後/proc/$!/status查看了信號配置。

SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003

這些是十六進制數字。這表明 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 指出的操作:disown在 bash 中使用該命令,這樣,如果 bash 必須退出,它不會向chromium-browser程序組發送 SIGHUP。您可以編寫一個函式來執行此操作:

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

引用自:https://unix.stackexchange.com/questions/162749