nohup不是后台运行的万能开关,它仅忽略SIGHUP信号;必须配合&实现后台执行,并显式重定向输出(如nohup cmd > log 2>&1 &),否则进程仍可能因前台阻塞、路径不可写或shell特性失效而中断。

nohup 不是“后台运行”的万能开关,它只负责忽略 SIGHUP 信号;真正让进程脱离终端、持续存活,必须配合 & 和输出重定向一起用,否则关终端后仍可能中断。
nohup 命令本身不自动后台执行
很多人误以为 nohup ./script.sh 就能后台跑,其实它只是忽略挂断信号,但仍在前台阻塞等待——你得手动按 Ctrl+C 才能回到 shell。真正生效的写法必须带 &:
-
nohup ./script.sh &:正确,进程放入后台作业队列 -
nohup ./script.sh:错误,卡在前台,关终端照样被杀 -
./script.sh &:也不行,没 nohup,关终端时收 SIGHUP 被终止
输出重定向不写全,日志会乱窜或失败
默认行为是往当前目录写 nohup.out,但这个路径常不可写(比如权限不足、磁盘满、目录被删),这时 nohup 会 fallback 到 $HOME/nohup.out——你根本不知道它写哪去了。更糟的是,如果两个地方都不可写,命令直接失败(退出码 127)。
- 安全写法:
nohup ./app.py > app.log 2>&1 &—— 明确指定路径,且合并 stdout/stderr - 静默运行:
nohup ./job.sh > /dev/null 2>&1 &—— 完全丢弃输出,避免日志膨胀 - 分离日志:
nohup ./server.sh > out.log 2> err.log &—— 错误和正常输出分开存,方便排查
关终端前别直接点 X,否则 session 可能提前断掉
实测发现:用 GUI 终端(如 GNOME Terminal)直接点击关闭按钮,有时会触发 session cleanup,导致 nohup 进程被连带 kill;而先输入 exit 再关窗口,更可靠。
- 推荐操作顺序:
nohup command > log 2>&1 &→ 看到[1] 12345或appending output to ...→ 输入exit→ 关窗 - 终极保险:
nohup command > log 2>&1 & disown -h %1——disown彻底剥离作业与当前 shell session - 验证是否真存活:
ps -p $(pgrep -f "command"),而不是只看jobs(后者只显示本 session 的作业)
复杂命令要用 sh -c 包一层
管道、重定向、变量展开等 shell 特性,在 nohup 后不能直接用。比如 nohup cat a.log | grep ERROR > result.txt & 会失败,因为 nohup 只接管第一个命令 cat,后面部分由当前 shell 解析,关终端就没了。
- 正确写法:
nohup sh -c 'cat a.log | grep ERROR > result.txt' > /dev/null 2>&1 & - 注意单引号包裹整个命令字符串,避免本地 shell 提前展开变量或通配符
- 如果命令里要引用变量,改用双引号并转义:
nohup sh -c "cat \$LOGFILE | grep ERROR" &
真正容易被忽略的点是:nohup 只解决 SIGHUP,不解决 stdin 断开、进程组继承、OOM killer 杀进程等问题。长期服务建议用 systemd 或 supervisord,nohup 更适合一次性长任务或临时调试。


















