这个问题很老了,我仍然不清楚为什么。
2014 年的原始问题:
在 Gnome 终端选项卡中,我跑了
$ nohup chromium-browser &
Run Code Online (Sandbox Code Playgroud)
但是当我关闭终端选项卡时,chromium-browser
也会退出。不nohup
应该阻止吗?吉尔斯说:
nohup 和 disown 都可以说是抑制 SIGHUP,只是方式不同。nohup 使程序最初忽略信号(程序可能会改变这一点)。nohup 还尝试安排程序没有控制终端,以便在终端关闭时内核不会向它发送 SIGHUP。disown 纯粹是 shell 内部的;它会导致 shell 在终止时不发送 SIGHUP。
那么 nohup 不是让铬浏览器忽略 SIGHUP 吗?
我也在其他可执行文件上看到了这一点,例如 Emacs(GUI 模式)。但不是在 xeyes 上。
发布问题时,这发生在 32 位 Ubuntu 12.04 上。
2015年更新,
现在我运行的是 Ubuntu 14.04,google-chrome
而不是chromium-browser
安装。以前发生在 Chrome 浏览器上的事情现在也发生在 google-chrome 上。nohup google-chrome 2>/dev/null &
当终端选项卡关闭时,它不会被关闭。/usr/bin/google-chrome
是一个指向 bash 脚本的链接/opt/google/chrome/google-chrome
。为什么nohup
应用于 bash 脚本不起作用?我们如何让它在 bash 脚本上工作?Python脚本呢?
Mar*_*ick 15
当您关闭 GNOME 终端窗口时,一个 SIGHUP 被发送到它正在运行的 shell。shell 通常会向它知道它创建的每个进程组发送一个 SIGHUP - 即使是开始的进程组nohup
- 然后退出。如果 shell 是bash
,它将跳过向用户标记的任何进程组发送 SIGHUP disown
。
运行命令nohup
使其忽略 SIGHUP,但进程可以改变它。当一个进程的 SIGHUP 的处置是默认的,那么如果它收到一个 SIGHUP,该进程将被终止。
Linux 提供了一些工具来检查正在运行的进程的信号设置。
铬浏览器 shell 脚本执行exec
编译后的应用程序,因此其进程 ID 保持不变。所以为了查看它的信号设置,我跑了nohup chromium-browser &
然后/proc/$!/status
查看了信号配置。
SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigCgt: 0000000180014003
Run Code Online (Sandbox Code Playgroud)
这些是十六进制数字。这表明 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);
}
Run Code Online (Sandbox Code Playgroud)
尽管有评论,父母忽略的信号并没有被忽略。SIGHUP 将杀死铬。
解决方法是执行@xx4h 指出的操作:disown
在 bash 中使用该命令,这样,如果 bash 必须退出,它就不会向chromium-browser
进程组发送 SIGHUP 。您可以编写一个函数来执行此操作:
mychromium () { /usr/bin/chromium-browser & disown $!; }
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5177 次 |
最近记录: |