如果让我给 Linux 运维新手挑一组必须提前掌握的会话保持命令,screen 和 tmux 一定排在最前面。原因很简单:你登录远程服务器跑长任务,最怕的不是任务慢,而是 SSH 网络闪断。断线意味着终端被关闭,原本挂在前台执行的脚本、正在训练的模型、要传很久的压缩包,都可能跟着一起中断。screen 和 tmux 解决的问题,就是让任务“脱离你当前的终端”继续运行,并且允许你随时重新连回来看状态。
这篇文章适合几类人:经常登录 Linux 服务器做部署的运维,跑数据训练、爬虫、批量转码的后端或算法同学,以及刚接触 Linux 想搞懂常用命令的初学者。内容不会只列命令,我会结合真实使用场景,把操作顺序、参数含义、出错原因和排查习惯一起讲清楚。
下面先把最关键的结论放在前面:screen 更克制、更老牌,适合老系统和最小化环境;tmux 更现代,适合日常开发机和需要分屏、多窗口、插件扩展的场景。无论选哪个,核心都是一句话——先跑通单条任务,再考虑批量,最后再谈自动化和复杂配置。
1. 会话保持要解决的不是“后台运行”,而是“断了还能接回来”
很多人刚看到 screen/tmux 时,第一反应是“这不就是让程序在后台跑吗”。这个理解不完整,甚至会导致用法错误。普通后台运行可以用 nohup 或系统服务解决,但 screen/tmux 的价值在于:任务一直在“一个终端界面里”运行,你随时可以把界面接回来继续操作。
1.1 一次断线,前台任务为什么会直接消失
Linux 里的多数命令是被“终端”管理的。当你通过 SSH 登录服务器后,Shell 会绑定到一个伪终端上。你在终端的命令行里敲python train.py,这个进程就把当前终端当成自己的输入输出窗口。
如果 SSH 网络突然断了,SSH 客户端进程退出,服务端会尝试清理这个会话。此时前台进程通常收到挂断信号,也就是常说的 SIGHUP。收不到信号、或无法处理信号时,进程就会结束。你过一会儿重新登录,会发现刚才的任务已经没了,屏幕上的最后几行日志也成了“临终遗言”。
这不是个别现象。我在实际运维和调试中见过太多案例:编译到一半断网、跑了一夜的数据同步因为凌晨网络抖动中断、远程给客户升级时手滑关错标签页。这类问题不是命令写错了,而是“程序的生命周期绑错了对象”。
1.2 nohup、systemd 和 screen/tmux 的使用边界
要解决长任务中断问题,并不是只能靠 screen/tmux。常见的方案主要有三类,各有各的边界。
nohup 适合“一次性、不关心过程、只看最终日志”的命令。它能让进程忽略挂断信号,日志重定向到文件,但进程跑起来后,你想再看它的实时输出就不太方便,更不能再往里面输入命令。
systemd 或 supervisor 适合“需要开机自启、自动重启、按系统服务方式管理”的常驻程序。如果你要跑的是 web 服务、消息队列消费者、定时任务守护进程,应该优先考虑 systemd,而不是把服务塞进 screen/tmux。
screen 和 tmux 适合“任务需要长期运行,但我还是希望随时进入它的执行环境继续操作”的场景。比如部署脚本跑到一半要选择分支、训练任务需要监控 loss 变化、调试时要在不同窗口反复切来切去。这些事 nohup 做不到,systemd 做起来又太重,正好是终端复用器的用武之地。
1.3 适合 screen/tmux 的四类典型任务
我建议你把这四类场景记下来,遇到就能直接对号入座:
- 远程执行耗时较长的部署或编译命令,同时需要看过程输出。
- 跑数据训练、批量接口请求、大量文件转换,想随时恢复界面看进度。
- 在服务器上维护多个任务窗口,比如一个窗口看日志,一个窗口执行命令,一个窗口查资源。
- 临时接管的服务器任务,自己当前终端随时可能关闭,但又不想让任务中断。
理解使用边界后,再看命令就不会乱。下一部分先用 screen 打开一个最小可用模型。
2. screen:先掌握五个命令,就能顶住日常远程值守
screen 的历史比 tmux 长,很多老版本 Linux 默认会装,或者只需要一个很小的软件包就能装上。它适合“尽量少依赖、快速起会话”的使用习惯。
2.1 安装 screen,并理解它会启动一个全新的 shell
Debian/Ubuntu 以及 WSL 里的 Ubuntu 环境,安装命令是:
sudo apt update sudo apt install -y screenRHEL、CentOS、Rocky、AlmaLinux 这类系统用:
sudo dnf install -y screen装完可以检查版本:
screen -v启动一个会话很简单:
screen -S work这里的work是会话名。加上名字之后,后续重连、管理、关闭都会方便很多,尤其是当一台服务器上有多个人都在用 screen 的时候。进入 screen 后,你会看到一个干净的新 Shell。这个 Shell 和当前 SSH 终端已经解耦,后面才是关键。
2.2 会话的新建、脱离、重连与强制接管
screen 最常用的命令其实就五个:
screen -S work # 新建一个名为 work 的会话 screen -ls # 查看本机有哪些 screen 会话 screen -r work # 重新连接到 work 会话 screen -d -r work # 先把另一端断开,再连接 screen -S work -X quit # 远程强制退出会话如果你想让正在执行的任务“离开当前终端”,不要直接关闭 SSH,而是按脱离快捷键。
在 screen 会话里,先按Ctrl+A,松开后再按d。看到类似[detached]的提示,说明你已经回到原来的 Shell,但会话里面的程序还在继续跑。
此时执行screen -ls,会看到类似这样的输出:
There is a screen on: 12345.work (Detached) 1 Socket in /run/screen/S-yourname.下次重新登录服务器后,输入:
screen -r work就可以重新看到当时的界面。如果某次异常断线导致显示Attached,但那个终端实际已经不在,可以执行:
screen -d -r work它会先让旧的屏幕端脱离,再由当前终端接管。这里需要提醒一句:强制接管前最好确认旧终端确实已经失效,否则会把还活着的另一端“踢掉”。
2.3 为什么报错“[screen is terminating]”通常不是事故
不少人在使用 screen 时看到过[screen is terminating],第一反应是出错了。其实大多数情况下这是正常提示,意思是“当前 screen 会话准备退出”。
最常见原因是你在屏幕里输入了exit,或者你启动 screen 时绑定了某条具体命令,那条命令执行结束后,screen 发现没有内容可以继续保留,就选择退出。比如有人习惯这样写:
screen -S demo python script.py脚本跑完,screen 就会显示[screen is terminating]并结束。这本身并不意味着脚本失败了,你需要检查的是脚本的执行结果和输出。
如果你希望“脚本执行完,screen 里面还留着可交互的 Shell”,可以这样启动:
screen -S demo bash -c "python script.py; exec bash"加了exec bash,脚本结束后不会立刻退出,而是把当前进程替换成交互式 Shell,方便你检查现场。这条经验在批量跑任务时尤其有用。
3. tmux:不仅是会话保持,还是终端里的“窗口管理器”
tmux 可以理解为 screen 的增强版。它保留了会话脱离、重连的核心能力,又加入了更清晰的多窗口、分屏、状态栏机制。现在很多开发机和云服务器的默认习惯已经转向 tmux。
3.1 安装 tmux 与服务器/会话/窗口/窗格四层结构
安装方式与 screen 类似:
# Debian/Ubuntu/WSL sudo apt install -y tmux # RHEL/Rocky/AlmaLinux sudo dnf install -y tmux检查版本:
tmux -V理解 tmux,建议先记住它的分层结构:服务端、会话、窗口、窗格。
- 服务端 tmux server 在后台运行,真正保存各个会话的进程状态。
- 会话 session 是你登录后看到的一整套工作区。
- 窗口 window 可以看成工作区里的多个标签页。
- 窗格 pane 是把一个窗口再切分成多个区域。
screen 也有窗口概念,但 tmux 把“窗口内的区域拆分”做得更顺手。这也是很多人从 screen 切换到 tmux 后最直接的感受。
tmux 默认前缀键是Ctrl+B。所有快捷键都以前缀键开头,按完再按具体功能键。下面的操作都需要记住这条规则。
3.2 以 dev 为示例的完整操作流
先新建一个会话:
tmux new -s dev会进入一个看似普通的 Shell,但实际上你已经在 tmux 的 dev 会话里。开始执行长任务,比如:
top按q退出后,想离开当前终端又不中断会话,就按脱离快捷键:
先按Ctrl+B,松开后按d。
回到普通 Shell 后,查看会话列表:
tmux ls输出类似:
dev: 1 windows (created Thu May ...)重新连接:
tmux attach -t dev如果另一端显示仍在连接,可以加-d参数,让其他客户端先脱离:
tmux attach -d -t dev任务全部结束后,直接关闭会话:
tmux kill-session -t dev这样比进入会话再一层层 exit 高效得多,尤其适合脚本化清理。
3.3 用分屏完成“窗口拆分”级的任务管理
tmux 比 screen 更有优势的地方是分屏。以前我排查线上问题时,常常要开好几个 SSH 窗口:一个窗口 tail 日志,一个窗口看磁盘,一个窗口执行命令。用 tmux 之后,这些都可以放到同一个窗口的不同窗格里。
分屏常用快捷键如下:
| 操作 | 按键 |
|---|---|
| 左右分屏 | Ctrl+B后按% |
| 上下分屏 | Ctrl+B后按" |
| 切换到上/下/左/右窗格 | Ctrl+B后按方向键 |
| 临时放大当前窗格 | Ctrl+B后按z,再按一次恢复 |
| 新建窗口 | Ctrl+B后按c |
| 切换到下一个窗口 | Ctrl+B后按n |
| 切换到上一个窗口 | Ctrl+B后按p |
| 预览并切换窗口 | Ctrl+B后按w |
| 重命名窗口 | Ctrl+B后按, |
| 进入复制/回看模式 | Ctrl+B后按[,按q退出 |
一个比较常用的排错画面是:
- 左侧窗格用
tail -f /var/log/app.log - 右上窗格用
df -h - 右下窗格准备执行下一步命令
这样一旦左侧日志出现新错误,你能在同一屏里立刻看到磁盘空间、负载状态,并且马上执行命令。整个布局在你脱离重连后仍然保留,不用重新拼。
注意,分屏本身也会消耗终端空间。窗格太多时,反而看不清关键日志。以我自己的习惯,同一屏最多三四个窗格,超过就直接开新窗口。
3.4 服务器重启之后,tmux 会话还能回来吗
这个问题必须说清楚:tmux 本身不是系统服务,它只是用户进程。服务器一旦重启,tmux server 也会停止,里面的所有窗口和会话都会消失。
所以不要把 tmux 当成“开机自动恢复工具”。如果服务器重启后任务还想继续,应该考虑两种方案:
- 把重要任务封装成 systemd 服务,由系统管理启动、停止和崩溃重启。
- 让 tmux 里的命令同时把完整输出写入日志文件,这样即使会话不在了,也有现场可以排查。
tmux 社区有一些恢复插件,比如 tmux-resurrect、tmux-continuum,可以在重启后尽量恢复之前的布局和部分程序状态。但插件需要提前安装、配置,并且依赖系统环境,不是默认功能。如果你是新手,先不用急着上插件,把日志落盘这一件事做好更实际。
4. screen 与 tmux 怎么选:一张对照表减少纠结
很多文章会直接告诉你“选 tmux”,但真实环境里并不总是这样。老服务器上的最小系统可能没有 tmux,也可能不方便联网装新包,这时候 screen 才是更稳的选择。
4.1 核心能力与易用性对比
我把两者的差异整理成一张表,方便你对照自己的环境判断。
| 对比项 | screen | tmux |
|---|---|---|
| 包体积 | 更小,老系统容易装 | 稍大,但主流源都有 |
| 默认会话 | 进入即 Shell | 分层明确,概念稍多 |
| 快捷键 | Ctrl+A前缀 | Ctrl+B前缀 |
| 多窗口 | 支持,操作稍简陋 | 支持,窗口管理体验更好 |
| 分屏 | 支持,但操作不如 tmux 直观 | 支持,分屏键位简单 |
| 状态栏 | 默认比较简洁 | 默认有状态栏,能显示时间、窗口名 |
| 复制回看 | 能用,交互偏老 | 体验更好,支持鼠标开关 |
| 配置项 | .screenrc | .tmux.conf |
| 扩展生态 | 偏少 | 插件社区更活跃 |
| 适用环境 | 老系统、生产机、极简环境 | 开发机、测试机、日常运维终端 |
这个表不是说 screen 不好。在长期没有人维护的老服务器上,screen 往往是最稳妥的“最后一根救命稻草”。但在自己可控的开发机和现代发行版上,tmux 的体验明显更顺。
4.2 不同环境下的选择建议
如果你的服务器是 CentOS 6 这类老系统,软件源可能很久没有更新,优先用系统自带的 screen。如果能接受复杂安装,也可以尝试编译 tmux,但风险和工作量都会增加。
如果你用的是 Ubuntu、Rocky、Debian 这类现代系统,并且可以正常使用软件源,我建议直接学 tmux。它更容易形成肌肉记忆,多窗口、分屏、状态栏这些能力在长时间排障时很有帮助。
还有一点值得注意:不要每天在两个工具之间横跳。screen 和 tmux 的快捷键习惯不同,混用容易造成误操作。选定一个作为主力,另一个只要知道怎么进入和退出就够了。
5. 长任务的标准操作流程与批量脚本化建议
会了基本命令之后,更重要的是把 screen/tmux 变成自己的工作习惯。很多人在“会用”和“用得好”之间差的就是一套稳定的操作流程。
5.1 手动任务的标准模板:启动、脱离、恢复、关闭
我自己处理长任务时,通常会固定走这几步:
第一步,先确认任务要在哪个目录、哪个虚拟环境或哪个用户下运行。登录后不要急着启动任务,先检查依赖和路径。
第二步,用 tmux 新建一个便于识别的会话。不要叫 test 或 111,会话名要能代表任务内容。比如:
tmux new -s deploy_api第三步,在会话里进入目标目录,把任务输出同时写到日志文件:
cd /opt/myapp source .venv/bin/activate python manage.py migrate 2>&1 | tee /tmp/deploy_api.log第四步,按Ctrl+B,再按d脱离会话。
第五步,之后想确认进度,重新登录服务器:
tmux attach -t deploy_api