1. 为什么nohup成了Linux后台任务的“标配”
干Linux运维这行,谁还没被“服务一断、进程就死”这事坑过。
我最早接触nohup是刚带生产环境那会儿,跑一个数据导入脚本,终端窗口一关,任务直接没了。后来才知道,终端关闭时内核会给进程组发SIGHUP信号,默认动作就是终止进程。nohup的全称是“no hang up”,作用就是忽略这个挂断信号,让命令在退出终端后继续跑。
这命令最朴素也最实用的场景就三类:一是远程SSH登录跑长任务,网络一抖或窗口误关,任务不受影响;二是服务器上跑需要持续运行的脚本,比如定时拉数、日志清理;三是配合重定向把输出存成文件,方便事后排查。我到现在都习惯性地把nohup和日志记录绑在一起用,因为它本质上是“守护进程”的轻量替代品,不需要systemd服务、不需要supervisor,一行命令就能把任务放后台,日志落盘。
这个命令适合谁?刚接触Linux的运维新人、经常在服务器上跑批处理脚本的开发,以及所有被“关终端丢任务”坑过的人。说白了,这是Linux常用命令里投资回报率极高的一条,花五分钟学会,后面能省下大量返工时间。
我接下来说的内容,不是把man手册抄一遍,而是把我这些年实际用nohup踩过的坑、验证过的写法、以及日志不完整这类高频问题的解决方案,一次说清楚。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. nohup基础用法:先搞懂命令本身再谈日志
2.1 nohup命令的标准格式
nohup的命令格式非常简单:
bash复制nohup 命令 [参数] [输出文件] &
& 的作用是把整个命令放到后台执行,终端能马上返回提示符。如果没有加 &,命令依然会阻塞当前终端,失去了“后台运行”的意义。
一个最典型的用法:
bash复制nohup ./start.sh > app.log 2>&1 &
这条命令的含义是:将 start.sh 放到后台运行,标准输出和标准错误全部追加写入 app.log 文件。
这里有个细节我反复跟同事强调:很多人只写 > app.log,这样的结果是标准输出进日志,但报错信息(标准错误)会直接丢到终端,终端一关,错误信息全没了。必须用 2>&1 把错误输出也重定向到同一个文件,日志才完整。
重定向 2>&1 的顺序不能乱。> app.log 2>&1 是先把标准输出指向文件,再把标准错误指向标准输出所指向的位置,结果两者都进文件。如果写成 2>&1 > app.log,顺序反了,标准错误会指向旧的标准输出——也就是终端,日志文件里依然缺错误信息。
2.2 nohup.out:默认日志文件是什么
如果不指定输出文件,nohup会默认把输出写到当前目录下的 nohup.out 文件。这听起来方便,但实际维护时是个坑。
我在一台跑批处理的服务器上遇到过:某个脚本在 /home/app 目录下启动,默认生成了 nohup.out,日志一写就是几个月,文件涨到十几个GB。排查磁盘告警时才发现是它,清理时还得先确认进程是否还在写,非常被动。
所以我的习惯是:只要用了nohup,就明确指定日志文件名,不要依赖默认的 nohup.out。文件名最好带上日期或任务名,比如 app-20250212.log,这样后续归档、清理都方便。
bash复制nohup python3 train.py > logs/train-$(date +%Y%m%d).log 2>&1 &
顺带一提:如果当前目录不可写,nohup会尝试把输出写到 $HOME/nohup.out,再不行就直接报错退出。这个行为在不同发行版上略有差异,但标准做法就是手动指定路径,别让系统替你决定。
2.3 查看后台进程和停止任务
启用了nohup的任务,Shell会返回一个进程ID,通常用 $! 获取:
bash复制nohup python3 long_task.py > task.log 2>&1 &
echo $! # 输出PID
后续想确
