nohup command > log 2>&1 & 是终端断开后保持程序运行的最直接有效方案,需同时满足忽略sighup、后台执行、输出重定向三要素,缺一不可。

nohup command > log 2>&1 & 是最直接有效的方案
终端断开后程序退出,本质是 shell 向子进程发送了 SIGHUP。nohup 的作用就是让命令忽略这个信号,配合 & 放入后台、> log 2>&1 重定向输出,三者缺一不可。
常见错误现象:
- 只写
nohup ./script.sh &,没重定向:输出默认写入nohup.out,若当前目录不可写会失败,且日志分散难排查 - 漏掉
&:命令仍在前台阻塞,终端一关照样退出 - 写成
nohup ./script.sh & > log 2>&1:重定向作用于当前 shell,不是nohup启动的进程,日志仍刷屏或丢失
正确写法必须把重定向放在 nohup 命令内部:
nohup ./script.sh > app.log 2>&1 &
执行后立刻返回提示符,可用 ps aux | grep script.sh 验证进程存在,用 tail -f app.log 实时看输出。
已运行的前台程序怎么补救?用 Ctrl+Z + bg + disown
程序已经在前台跑着,又不想中断重来——这是高频真实场景。不能 kill 再重跑,得“热迁移”到脱离终端的状态。
操作顺序不能错:
- 按
Ctrl+Z暂停进程(变成Stopped状态) - 运行
bg让它在后台继续执行 - 运行
disown -h %1(%1是jobs显示的作业号),剥离其与当前 shell 的会话关联
注意:disown 不处理输出重定向。如果原命令没重定向,日志仍试图写终端,断开后可能出错或静默失败。补救时建议立即重定向输出,例如:nohup -p $(pgrep -f "script.sh") > app.log 2>&1 &(部分系统支持 nohup -p,但兼容性不如手动重定向可靠)。
需要交互或随时查看输出?选 screen 或 tmux
当程序有实时日志滚动、需中途输入指令(比如 python manage.py runserver)、或要分屏对比多个任务时,nohup 就不够用了——它彻底切断了交互能力。
screen 和 tmux 的核心价值是创建独立会话(session),进程归属 session 而非终端,断开后可重连。
-
screen -S myjob新建会话 → 运行程序 →Ctrl+A然后D分离 → 下次screen -r myjob接回 -
tmux new -s work→ 运行 →Ctrl+B然后D→tmux attach -t work接回
区别在于:tmux 原生支持竖切/横切面板、复制模式、快捷键绑定,适合多任务并行;screen 更轻量,老系统预装率高。两者都不依赖用户登录状态,但会话本身仍属当前用户,系统重启后不会自动恢复。
长期服务必须用 systemd,别用 nohup 顶替
把 nohup node app.js > log 2>&1 & 当生产服务用,是运维大忌。它缺乏进程监控、崩溃自拉起、启动顺序依赖、资源限制等关键能力。
真正该走 systemd 的场景:
- Web 服务、数据库代理、消息队列消费者等需 7×24 运行的组件
- 要求开机自启、故障自动重启(
Restart=always)、启动超时控制(TimeoutSec=30) - 需要以特定用户身份运行、限制内存/CPU(
MemoryLimit=512M)
配置文件路径固定为 /etc/systemd/system/myapp.service,启用流程三步:systemctl daemon-reload → systemctl enable myapp → systemctl start myapp。日志统一走 journalctl -u myapp -f,不操心文件轮转。
容易被忽略的一点:systemd 服务默认不继承用户环境变量(如 $HOME、$PATH),Environment= 或 EnvironmentFile= 必须显式声明,否则脚本里调用的命令可能找不到。











