nohup 命令详解:如何在 Linux 下让后台任务稳定运行
在 Linux 中运行后台任务,最让人担心的是什么?终端一旦关闭,进程就会“断线”终止。这时,nohup 命令就是帮你牢牢稳住后台进程的救星。但要想真正理解它的工作原理,得先弄清楚SIGHUP 信号——它才是导致“断线”的罪魁祸首。
SIGHUP 信号:进程断开连接的幕后推手

SIGHUP 信号通常在以下三种情况下被发送给对应进程,我们逐一分析:
- 终端关闭时,信号会发送给 session 的首进程以及作为 job 提交的进程(也就是用
&符号提交的后台任务); - 当 session 的首进程退出时,该信号会发送给该 session 中前台进程组的每一个进程;
- 如果父进程退出导致进程组变成孤儿进程组,并且该进程组中有进程处于停止状态(比如收到了
SIGSTOP或SIGTSTP信号),那么该信号就会发送给这个孤儿进程组中的每一个进程。
举个例子你就明白了:当你登录 Linux 系统时,系统会为你分配一个终端(Session)。你在终端里运行的所有程序——无论是前台进程组还是后台进程组——都属于这个 Session。当你退出登录时,前台进程组和那些有终端输出的后台进程都会收到 SIGHUP 信号。这个信号的默认操作就是终止进程,因此前台进程组和那些有终端输出的后台进程会直接挂掉。
nohup 命令:让进程忽略挂断信号
nohup 的作用非常直接:它不会断开与终端的连接,而是让你的脚本或命令忽略 SIGHUP 信号,同时自动把 stdout/stderr 重定向到一个名为 nohup.out 的文件里。这样一来,即使你注销了终端,命令依然能在后台悄无声息地持续运行。
不过需要注意:nohup 并不会自动把命令放到后台执行——它只是帮你屏蔽了挂断信号。要想让程序真正在后台运行,你还得加上 & 符号,明确告诉 shell:“嘿,放到后台去!”
如果想查看当前有哪些作业正在运行,可以使用 jobs 命令。如果 jobs 都找不到某个进程了,那就说明它已经不再是这个 shell 的子进程了。
另外,即便已经用 nohup 启动了程序,你也可以用 fg 命令把它带回前台。不过带回前台并不会改变输出重定向——它仍然会老老实实地往 nohup.out 里写数据。
测试 nohup 是否真的有效
如何确认 nohup 真的能防止退出登录后脚本停掉?我们来做一个简单测试:
#!/bin/bash
for i in `seq 1000`; do
echo "$i";
sleep 2;
done;
然后运行:
nohup sh t.sh 2>&1 &
退出终端再重新登录,你会发现脚本还在后台老老实实地跑着,输出也都写进了 nohup.out。
nohup 与 & 的区别与配合
很多人容易把 nohup 和 & 混为一谈,实际上它们各司其职。& 的作用是把命令放到后台运行,但退出 shell 时,shell 会给子命令发送一个 SIGHUP 信号(相当于执行了 kill -SIGHUP ),子命令照样会挂掉。而 nohup 则负责捕获这个信号并忽略它,让信号根本传不到应用程序那里。所以两者配合使用才是最佳实践:nohup 防挂断,& 放后台。
如果你使用的是 bash,可以用 shopt | grep hupon 来检查当前 shell 是否会在退出时向子进程发送 SIGHUP。如果 huponexit 是 off 状态,那么退出时就不会向终端所属任务发送 SIGHUP 信号。想激活这个选项就运行:
shopt -s huponexit
不过多数发行版默认是关闭的,所以即便你不加 nohup,有时退出终端后台任务也未必会停——但这属于“碰运气”,并不靠谱。
将已经运行的进程转移到 nohup 保护下
如果已经有一个进程在前台跑着,突然想起来需要把它放到后台并且不受终端关闭的影响,该怎么办?有套路:
- 先按
Ctrl + Z把程序暂停下来,回到 shell。 - 用
bg命令让它在后台继续运行。 - 用
disown -h [job-spec]把它从 shell 的作业表中摘掉([job-spec]是作业编号,比如%1代表第一个正在运行的作业,先使用jobs查一下编号),这样终端关闭时这个作业就不会被终止。
要是连 Ctrl + Z 都不管用(比如某些进程根本不吃这一套),那就另开一个终端,用 ps 找到那个进程的 PID,然后执行:
kill -SIGSTOP PID
kill -SIGCONT PID
SIGSTOP 会暂停进程,SIGCONT 则让它在后台恢复运行。这样一来,关闭两个终端都不会影响到你的进程了。
更多学习资料
如果想深入研究,可以查阅 Linux 的 nohup 命令手册页,以及 Linux Signal 机制——尤其是 Golang 里如何处理这些信号,都是挺有意思的话题。
