为什么nohup后台进程被杀死?


10

我尝试通过远程会话启动Shell脚本,该会话使用命令在后台启动进程。

nohup python3 run.py > nohup.out &

当远程会话关闭时,该进程将被消息杀死:

捕获信号SIGHUP

SIGHUP被捕获但未被守护。正在退出。

我不明白 为什么使用nohup&在后台启动该进程会被杀死?


1
我曾经对Shell作业控制的所有意外行为感到困惑。现在,我只使用tmux和完全忽略nohup或放弃或后台任务。
任思远'18

Answers:


10

您的Python程序撤消nohup

nohup忽略hangup信号,SIG_IGN然后在同一过程中链式加载程序。

您的Python程序会立即重置挂断信号的信号处理,并安装自己的信号处理程序。该处理程序检查一个内部函数(如果我已经看过一个错误的假设,则该函数的设计不是很好),并确定接收到挂断信号时的适当措施是打印该消息。然后退出。

设计上的Python程序不可nohup用。在具有作业控制外壳和POSIX会话/作业语义的系统上,您需要disown对作业进行处理,以使外壳永远不知道要向其发送挂断信号。

(即使在systemd操作系统上这还不够。由于systemd的人们对他们的用户空间登录会话机制有些了解,因此,您还需要确保systemd的机制向系统发出信号,而不是挂断信号,以便每次注销时的登录会话也不会启动。)

进一步阅读


3
是由他们的Python程序执行的,还是在其背后默默执行的Python解释器(/运行时环境)?
ilkkachu

而且,在Mac OS上,即使开始使用ssh会话,退出ssh会话也会杀死shell工作nohup。尚未找到解决办法
imhotap '18

好吧,如果问题出在信号处理程序上,那么OP可以简单地将信号处理程序更改为不会杀死进程的处理程序。这应该独立于谁安装这种信号处理程序来工作。我想补充一下有关ssh的信息:有时,即使该进程保持活动状态,也可能会遇到麻烦。几年前,我花了很多时间试图理解一些权限错误,而最终的罪魁祸首是Kerberos:当ssh会话关闭时,令牌已过期,因此我不得不创建新的令牌来代替这些令牌ssh会话。
巴库里

我尝试了@JdeBP setsid nohup python3 run.py > nohup.out &setsid解决了此问题。这是正确的方法吗?
Mostwanted Mani
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.