nohup仅解决终端断开导致进程终止的问题,需显式重定向输出(如nohup cmd > log 2>&1 &),并配合ps、tail验证;长期服务应使用systemd(含自动重启、日志管理、开机自启),screen/tmux仅适用于交互调试,setsid/disown属临时补救手段。

没有“永久”这回事,只有“按需持久化”。选错方法,程序可能在 SSH 断开、系统重启或崩溃后立刻消失。
nohup 命令适合临时任务,但容易被误用
很多人以为 nohup your_command & 就万事大吉,其实它只解决“终端断开”这一个环节。常见问题包括:
- 没重定向输出,
nohup.out写满磁盘或因权限失败导致命令根本没跑起来 - 直接关闭终端窗口(而非先
exit),部分 shell 会连带 kill 掉未完全 detach 的子进程 - 程序自己崩溃了,
nohup不会拉它起来;服务器重启后,进程彻底消失
正确写法必须显式重定向:
nohup node app.js > /var/log/myapp.log 2>&1 &
然后用 ps aux | grep app.js 确认 PID 存在,再用 tail -f /var/log/myapp.log 看日志是否实时写入。
systemd 是长期服务的默认选择
如果你要部署的是 Web 服务、API、队列消费者等需要“开机自启 + 自动重启 + 日志轮转”的程序,systemd 是现代 Linux(Ubuntu 16.04+/CentOS 7+)唯一推荐的方案。关键点:
- 服务文件必须放在
/etc/systemd/system/下,不能放用户目录 -
Restart=always能应对崩溃,但不会在程序正常退出时重启(避免无限循环) - 必须执行
systemctl daemon-reload才能让新配置生效,否则start会报 “unit not found” - 日志用
journalctl -u myapp.service -f查,别再去翻.log文件
示例最小可用配置:
Linux系统管理专家,覆盖12大模块:用户权限、SSH、存储、网络、systemd、防火墙、日志监控、备份恢复、TLS证书、Ansible、容器、IaC。提供配置、验证、加固、监控、备份、自动化、故障排查、回滚闭环。关键词:useradd、sudo、sshd_config、chmod、SEL...
[Unit] Description=My Node App After=network.target [Service] Type=simple User=deploy WorkingDirectory=/opt/myapp ExecStart=/usr/bin/node /opt/myapp/app.js Restart=always RestartSec=5 [Install] WantedBy=multi-user.target
screen 或 tmux 适合交互式调试,不适合生产部署
它们本质是“虚拟终端”,不是进程管理器。你用 screen -S myapp ./run.sh 启动后,虽然能 Ctrl+A D 分离,但存在几个硬伤:
- 用户登出后 session 可能被清理(尤其 systemd-logind 配置了
KillUserProcesses=yes) - 无法自动拉起崩溃进程;
systemctl restart也管不到 screen 里的进程 - 日志分散、难聚合;
screen -r连上去看到的只是当前终端缓冲区,不是完整运行记录
真正要用,得配合脚本自动化创建和发送命令,比如:
screen -dmS myapp screen -S myapp -X stuff 'cd /opt/myapp\n' screen -S myapp -X stuff 'npm start\n'
但这已经偏离初衷——你是在模拟人操作,而不是托管服务。
setsid 和 disown 是补救手段,不是首选方案
当程序已经前台启动了,又不想中断它,才考虑这两个命令:
-
disown %1:仅对当前 shell 的作业有效,且该作业必须还没收到SIGHUP(即你还没退出 terminal) -
setsid your_command:绕过 session leader,让进程彻底脱离终端控制,但无日志重定向、无重启逻辑、无状态管理
它们都不能替代 systemd 的生命周期管理能力。真遇到紧急情况,优先用 systemctl stop + 替换 service 文件 + daemon-reload,比现场打补丁更可靠。
最常被忽略的一点:所有方案都依赖正确的用户权限和工作目录。用 root 启动的服务,如果 WorkingDirectory 是普通用户家目录,systemd 会静默失败;nohup 写日志到 /var/log/ 却没给目录写权限,也会默默退出。动手前,先确认路径可写、用户有权限、命令能手动执行成功。










