
以下命令在 Debian 11/12、Ubuntu 20.04/22.04、CentOS 7/8 上验证过,操作环境包括搬瓦工加拿大温哥华CABC_1节点(1核1G内存、20GB SSD、1Gbps带宽)、LuckVM香港CN2 GIA节点(1核1G/60GB+10GB NVMe/10Mbps CN2线路,月付11)、LuckVM波兰华沙节点(1核512M/5GB SSD/1Gbps Tier1线路,月付$4.93)、DMIT洛杉矶DDoS Shield高防节点(1核1G内存、20GB SSD)、Vultr迈阿密节点(1核1G内存、25GB SSD)、AWS Lightsail东京节点(1核1G内存、30GB SSD),全程root或sudo权限执行。本文只记录命令操作本身,不做任何产品推荐或性能评价,服务器仅作为操作环境。
用nohup、screen、tmux后台运行命令
一、问题:SSH断连后正在运行的命令就没了
通过SSH连接到服务器执行长时间命令(编译、备份、同步、数据处理)时,一旦网络波动断开SSH、或不小心关闭终端窗口,正在运行的进程就会收到SIGHUP(挂断)信号被终止,任务就白跑了。比如编译一个大型程序要跑半小时,跑了10分钟断网就得重来。
后台运行命令有几种方式,按简单到复杂:& 放后台 → nohup 不挂断 → disown 分离已启动进程 → screen 虚拟终端 → tmux 终端复用 → systemd 服务管理。不同场景用不同方式。
二、最简单:& 放后台运行
在命令末尾加一个 &,命令就放到后台执行,立刻返回shell提示符可以继续输入其他命令:
# 格式:命令 &
ping 8.8.8.8 > ping.log &
[1] 25831
输出 [1] 25831 表示这是第1个后台作业(job),PID是25831。
jobs 查看当前后台作业:
jobs
[1]+ Running ping 8.8.8.8 > ping.log &
+号表示最近一个放入后台的作业,Running是正在运行。
fg 调回前台:
fg %1 # 把job 1调回前台
fg # 默认调回带+号的最近作业
bg 让暂停的作业继续在后台运行:
# Ctrl+Z 暂停前台进程,然后bg放到后台继续
^Z
[1]+ Stopped ping 8.8.8.8
bg %1
[1]+ ping 8.8.8.8 > ping.log &
注意:单独用 & 只是放到后台,并没有脱离当前shell,关闭终端或SSH断开时进程还是会收到SIGHUP被终止。要真正断开后继续运行,需要配合nohup或disown。
三、nohup:不挂断运行
nohup(no hang up)的作用就是让命令忽略SIGHUP信号,关闭终端后进程不会被终止。这是最常用的后台运行方式。
基本用法:
# 格式:nohup 命令 &
nohup ping 8.8.8.8 > ping.log &
[1] 25840
# nohup: ignoring input and appending output to 'nohup.out'
输出重定向:不指定输出重定向时,nohup会把stdout和stderr都写到当前目录的 nohup.out 文件。长时间运行会让nohup.out越来越大,建议主动指定重定向:
# 标准输出写output.log,标准错误写error.log
nohup ./build.sh > output.log 2> error.log &
# stdout和stderr都写到同一个文件
nohup ./build.sh > output.log 2>&1 &
# 丢弃所有输出(不保留日志,适合确定不需要输出的场景)
nohup ./long_task.sh > /dev/null 2>&1 &
之前在LuckVM香港节点上编译一个需要跑20多分钟的程序,直接 nohup make -j$(nproc) > build.log 2>&1 & 放到后台,退出SSH等15分钟再连上去查看build.log看编译结果即可。
查看nohup进程:
ps aux | grep long_task
# 或者直接看PID
ps -p 25840
停止nohup进程:
kill 25840
# 或者通过pkill按进程名
pkill build.sh
四、disown:把已启动的进程从shell分离
有时候命令已经跑起来了,突然想起要断开SSH但之前没加nohup,不想中断正在跑的任务,可以用disown:
# 1. 先按 Ctrl+Z 暂停当前前台进程
^Z
[2]+ Stopped rsync -avz /data/ backup:/data/
# 2. 用bg让它在后台继续运行
bg %2
[2]+ rsync -avz /data/ backup:/data/ &
# 3. disown把它从shell作业表中分离,关闭终端不会被kill
disown %2
# 如果不指定job号,disown默认对最近一个作业操作
disown
disown -h 参数:不是移除作业,而是标记该作业不接收SIGHUP,jobs还能看到它。
之前在LuckVM韩国首尔节点上rsync同步一个30GB的目录备份,跑了一会才发现忘了加nohup,Ctrl+Z暂停→bg→disown三步操作后,放心断开SSH,第二天再登录确认同步完成。
五、screen:虚拟终端会话(可随时断连重连)
screen是一个虚拟终端管理器,创建的screen会话独立于SSH连接,断开后会话继续运行,下次可以重新连接(attach)进去查看。适合需要随时回去看输出、和进程交互的场景。
安装:
# Debian/Ubuntu
apt install screen -y
# CentOS
yum install screen -y
基本操作流程:
# 1. 创建一个命名会话(-S指定名字方便辨认)
screen -S build
# 2. 进入screen后,正常执行命令
./long_build.sh
# 3. 临时退出(detach)但不关闭会话:按 Ctrl+A,然后按 D
[detached from 12345.build]
# 回到原shell,可以安全退出SSH
# 4. 下次登录后,查看所有screen会话
screen -ls
There is a screen on:
12345.build (03/15/2026 02:30:00 PM) (Detached)
# 5. 重新连接(attach)回去
screen -r build
# 会话还在,之前的命令输出都能看到
# 6. 会话用完了,在screen内部exit退出,会话就关闭了
exit
[screen is terminating]
常用快捷键(都要先按Ctrl+A):
强制接管别人的会话(会话attached状态但连接断开了):
screen -d -r build
# -d 先detach再attach
六、tmux:更现代的终端复用器
tmux和screen功能类似,但更现代、功能更强(支持分屏、状态栏、脚本化配置),是很多运维人员的首选。
安装:
apt install tmux -y
# 或 yum install tmux -y
基本操作:
# 创建命名会话
tmux new -s work
# 执行命令后临时退出(detach):Ctrl+B 然后按 D
# 查看会话列表
tmux ls
# 重新连接
tmux attach -t work
# 或简写
tmux a -t work
常用快捷键(先按Ctrl+B,再按其他键):
之前在LuckVM波兰节点上同时跑多个监控脚本,用tmux分成三个窗格分别跑日志监控、ping测试、磁盘IO监控,一个界面同时看三个任务,detach后脚本继续运行。
七、需要开机自启动:写systemd服务
前面的nohup/screen/tmux都是会话级别,服务器重启后任务不会自动启动。需要真正长期后台运行、开机自启的进程,应该写systemd服务:
创建服务文件 /etc/systemd/system/myapp.service:
[Unit]
Description=My Long Running App
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/myapp.sh
Restart=on-failure
RestartSec=5
StandardOutput=append:/var/log/myapp.log
StandardError=append:/var/log/myapp.log
[Install]
WantedBy=multi-user.target
启用并启动:
systemctl daemon-reload
systemctl enable myapp
systemctl start myapp
systemctl status myapp
这种方式是最规范的后台服务管理方式,适合常驻服务(Web服务、采集脚本、定时任务等)。
八、其他方式简要
setsid:开一个新会话运行命令,效果和nohup类似:
setsid ./long_task.sh
at 定时执行:指定时间运行一次命令:
echo "./backup.sh" | at 02:00
cron定时任务:周期性重复执行,前面crontab那篇已经写过。
九、实战场景
场景1:rsync大文件同步不中断
大文件同步耗时久,配合nohup后台执行,日志写文件:
nohup rsync -avz --progress /data/ user@remote:/data/ > rsync.log 2>&1 &
tail -f rsync.log
场景2:编译大型软件
编译可能跑几十分钟,用screen:
screen -S compile
cd /usr/src/xxx
./configure && make && make install
# Ctrl+A d 退出
# screen -r compile 随时回来看
场景3:Python脚本常驻运行
临时脚本用nohup,正式服务写systemd:
# 临时跑
nohup python3 monitor.py > monitor.log 2>&1 &
场景4:同时监控多个日志
tmux分屏多窗格:
tmux new -s logwatch
# Ctrl+B % 左右分屏
# 左边 tail -f /var/log/nginx/access.log
# 右边 tail -f /var/log/nginx/error.log
十、易错点和注意
- nohup.out会越写越大:不加重定向所有输出都写nohup.out,运行几个月能撑满磁盘,建议主动用 >log 2>&1 或 >/dev/null 重定向。
- & 不等于后台稳定运行:单独用&,断开SSH进程还是会被kill,必须配nohup/disown。
- screen/tmux 要记得exit关闭:开了不用的会话会一直占着系统资源,screen -ls 和 tmux ls 定期清理。
- nohup执行相对路径问题:nohup启动脚本时,脚本内的相对路径是相对于执行nohup时的工作目录,不是脚本所在目录,建议脚本内先cd或用绝对路径。
- 环境变量可能不同:nohup启动的进程环境变量和交互式shell不完全一样(比如PATH),脚本里最好写绝对路径。
- systemd服务的Restart=always要谨慎:程序正常退出也会被自动重启,按需选on-failure或on-abnormal。
- 不要在screen/tmux里跑太多高负载任务:开太多会话占资源,定期清理不用的。
十一、实用经验
- 临时跑几分钟但不想因为断连中断:nohup 命令 >log 2>&1 &,简单够用。
- 命令已经跑了才想起要后台:Ctrl+Z → bg → disown 三步救场。
- 需要和进程交互(随时回来输入命令看输出):用tmux(更推荐)或screen。
- 长期常驻服务,开机自启:写systemd service文件,最规范最可靠。
- 跑完的后台进程记得看日志确认结果(tail -f log看输出,echo $?看退出码)。
- nohup加完后可以用 ps aux | grep 命令名 确认进程在跑,disown后jobs可能看不到但ps能看到。
- tmux配置~/.tmux.conf可以把快捷键改成自己习惯的,比如开启鼠标支持、改状态栏。












