关闭GNOME终端窗口时,会将SIGHUP发送到它正在运行的shell。Shell通常会将SIGHUP发送到它知道创建的每个进程组-甚至是以nohup
- 开头的进程组,然后退出。如果shell是bash
,它将跳过向用户标记为的任何进程组发送SIGHUP disown
。
运行带有的命令nohup
会使它忽略SIGHUP,但是该过程可以更改它。如果默认情况下将SIGHUP分配给进程,则如果它收到SIGHUP,则该进程将终止。
Linux提供了一些工具来检查正在运行的进程的信号设置。
Chrome浏览器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必须退出,则不会将SIGHUP发送到chromium-browser
进程组。您可以编写一个函数来做到这一点:
mychromium () { /usr/bin/chromium-browser & disown $!; }