终端关闭时子进程自动退出是因为内核向前台进程组发送sighup信号;防止方法有四类:nohup忽略信号、setsid创建新会话、screen/tmux保持交互会话、systemd管理长期服务。

终端关闭时子进程自动退出,是因为内核向当前会话的前台进程组发送了 SIGHUP(挂起信号)。防止的关键不是“阻止内核发信号”,而是让目标进程不接收或不响应它。核心方法分两类:忽略信号,或脱离原会话。
用 nohup 忽略 SIGHUP
nohup 的作用是调用 signal(SIGHUP, SIG_IGN),把挂起信号设为忽略状态,再执行命令:
- 基本用法:
nohup python3 script.py > output.log 2>&1 & - 输出默认写入
nohup.out,建议显式重定向,避免日志混乱 - 进程仍属于原会话和进程组,只是对 SIGHUP 不做任何反应
- 适合一次性、无需交互的后台任务,简单直接
用 setsid 创建新会话
setsid 启动进程时,会调用系统函数 setsid() 创建全新会话,使进程成为会话 leader,彻底脱离原终端控制:
- 用法示例:
setsid python3 script.py & - 该进程不再属于原 bash 会话,自然收不到 SIGHUP
- 不会继承父进程的控制终端(tty),也不会被终端关闭影响
- 比 nohup 更彻底,但不提供会话管理界面
用 screen 或 tmux 保持交互会话
screen 和 tmux 是终端复用工具,它们启动一个持久虚拟终端,所有在其内运行的进程都归属新会话:
- 启动:
screen -S myjob或tmux new -s myjob - 运行程序后,按
Ctrl+A+D(screen)或Ctrl+B+D(tmux)分离会话 - 断开 SSH 或关闭终端后,会话仍在后台运行;重新连接后可用
screen -r或tmux attach恢复 - 支持多窗口、复制粘贴、日志回溯,适合需要中途查看或调试的任务
用 systemd 管理长期服务
对于需开机自启、自动重启、日志集成的服务级进程,systemd 是更规范的选择:
- 编写 unit 文件(如
/etc/systemd/system/myservice.service),指定Type=simple或Type=forking - 启用并启动:
sudo systemctl daemon-reload && sudo systemctl enable --now myservice - systemd 自动处理会话隔离、信号屏蔽(默认忽略 SIGHUP)、崩溃重启、资源限制等
- 日志统一由
journalctl -u myservice查看,无需手动重定向











