终端关闭中断任务是因为内核向前台进程组发送SIGHUP信号;防止方法有:nohup(忽略SIGHUP)、setsid/screen/tmux(脱离原会话)、systemd(独立服务管理)。

Linux 通过信号机制控制进程生命周期,终端关闭时默认会向所属会话中的前台进程组发送 SIGHUP(hangup)信号,导致任务中断。要防止中断,核心思路是让进程不响应或不接收这个信号——要么忽略它,要么脱离原会话。
为什么终端关闭会中断任务
当你在终端中运行命令(如 python train.py),该进程默认成为当前 bash 会话的子进程,归属于同一个会话(session)和进程组(process group)。一旦终端关闭或 SSH 断连,内核会向整个会话的前台进程组广播 SIGHUP。多数程序未捕获该信号,直接退出。
nohup:让进程忽略 SIGHUP
nohup 的本质是调用 signal(SIGHUP, SIG_IGN),将挂断信号设为忽略状态,再执行目标命令。配合 & 后台运行,就能避开终端控制流:
-
nohup python3 app.py > app.log 2>&1 &:标准输出和错误都写入日志,进程忽略 SIGHUP 并后台运行 - 输出默认存为
nohup.out,除非显式重定向 - 注意:nohup 不改变进程所属会话,只修改信号处理行为
setsid 和 screen/tmux:让进程脱离原会话
另一种方式是让进程不再属于原终端会话,从而根本收不到 SIGHUP。这靠创建新会话实现:
-
setsid python3 app.py &:直接启动一个新会话,进程变成会话 leader,与终端解耦 -
screen -S job或tmux new -s job:启动虚拟终端会话,所有在其内运行的进程都归属新会话;按Ctrl+A+D(screen)或Ctrl+B+D(tmux)分离后,会话持续存在 - screen/tmux 还保留了交互能力,适合需要实时查看、调试或输入的场景
systemd:面向服务的长期守护
对生产环境的长期服务(如 Spring Boot 应用),推荐用 systemd 管理:
- 以独立服务单元运行,完全脱离用户会话,不受登录状态影响
- 支持开机自启、崩溃自动重启、资源限制、日志集中管理(
journalctl -u myapp) - 避免了 nohup 或 screen 的手动运维短板,更适合可观测、可维护的服务部署
不复杂但容易忽略:关键不在“后台”,而在“是否隶属终端会话”和“是否响应 SIGHUP”。选哪种方式,取决于任务性质——临时脚本用 nohup,交互任务用 screen/tmux,长期服务走 systemd。


















