暗色模式

tmux 终端复用实战:从会话管理到分屏与远程任务持久化

技术教程
2026-08-08
8
0

为什么需要 tmux

在服务器上跑过长时间任务(部署、编译、备份、日志追踪)的同学,大概率都经历过这样的痛:SSH 连上去,任务跑到一半,网络一抖连接断开,前台进程随之被 SIGHUP 杀掉,几个小时的活白干。

tmux 就是解决这个问题的终端复用器(terminal multiplexer):它把终端会话放到后台独立运行,SSH 断开只是"分离"了你的视图,会话里的任务照跑不误,重连后随时可以"重新附着"回来。除此之外,它还能在一个窗口里开多个窗格(Pane)同时监控多台服务、复制粘贴历史输出、给每个项目独立会话——是 Linux 运维与开发者的刚需工具。

同类工具还有更老的 GNU screen,tmux 在分屏布局、配置语法、活跃维护上都更现代,本文以 tmux 为主。

安装与版本

Ubuntu/Debian 系直接 apt 安装,几秒完成:

sudo apt update
sudo apt install -y tmux

验证版本:

tmux -V

Ubuntu 24.04 下安装的 tmux 3.4 及软件源中的版本信息

如上图所示,Ubuntu 24.04 官方源( noble-updates)当前提供的是 tmux 3.4。如果你想要更新的大版本(2024 年 10 月发布的 3.5a,以及后续的 3.6 系列),可以从 tmux 官方 GitHub Releases 下载预编译包(仓库 tmux-builds 提供 amd64/arm64 二进制)或源码编译,日常使用 3.4 功能完全够用。

理解三个层级:会话、窗口、窗格

tmux 的管理结构是三层嵌套,记住它就掌握了 tmux 的骨架:

  • Session(会话):一个独立的"工作区",包含若干窗口。你的 SSH 连接附着在会话上,任务跑在会话里——断线丢的是连接,不是会话。
  • Window(窗口):会话里的"标签页",一个会话可以开多个窗口,Ctrl-b c 新建、Ctrl-b 0~9 切换。
  • Pane(窗格):窗口的分屏区域,一个窗口可以切成左右上下多个窗格,各跑各的命令。

命令行的常用别名:tmux ls 列出会话、tmux a 等于 tmux attachtmux new 等于 tmux new-session

快速上手:创建、分离、恢复

创建并进入一个命名会话

tmux new -s mysession

不带名字直接 tmux,会创建默认编号的会话。进入后你会看到底部出现一条绿色的状态栏,上面有会话名、窗口列表等信息,说明已在 tmux 内部。

分离:回到原来的 shell

在 tmux 里按 Ctrl-b d(先按 Ctrl-b 松开,再按 d),会话就"分离"了——注意是分离不是退出,屏幕回到普通 shell,会话里的任务继续在后台跑。

查看与恢复

tmux ls          # 列出所有会话
tmux attach -t mysession   # 重新附着到指定会话

tmux ls 是排查服务器上有哪些 tmux 会话的第一命令,后面实战会反复用到。

实战:SSH 断线后任务不丢

假设你要在服务器上跑一个需要十几分钟、按步输出的部署任务,直接在前台跑,SSH 一断就前功尽弃。正确的做法是:后台创建会话 → 把任务"送"进会话 → 断线重连后 attach 回去看进度。

下面的演示在服务器上真实执行(后台会话 + 发送命令 + 查看状态):

tmux new -d -s deploy    # -d 表示后台创建,不占用当前终端
tmux send-keys -t deploy 'for i in $(seq 1 20); do echo "[$(date +%T)] 部署任务进行中: 第 $i 步"; sleep 1; done' Enter
sleep 3
tmux ls
tmux capture-pane -t deploy -p | grep '^\[' | head -3

会话持久化演示:后台会话运行长任务,tmux ls 显示会话仍在,任务按步输出

看上面的输出:

  • tmux new -d -s deploy 在后台创建名为 deploy 的会话,当前终端不受影响;
  • tmux send-keys -t deploy '...' Enter 把一条循环命令(20 步、每秒一步,模拟长任务)以按键形式发送进 deploy 会话的 shell 里执行——-t 指定目标会话或 会话:窗口.窗格;
  • tmux ls 显示 deploy 会话存在;
  • tmux capture-pane 直接抓取会话当前屏幕内容,过滤出任务输出——任务正在按步推进。

现在模拟断线:直接关掉 SSH 连接(exit 或断开网络),重连服务器后执行:

tmux attach -t deploy

你会看到任务从断开前的位置继续往下跑,一步都没丢。这就是 tmux 对远程运维最大的价值。capture-pane 在没法 attach 的场景(比如只想瞄一眼输出)也特别实用。

分屏:一个窗口多任务并行

运维场景里经常要同时盯着多个输出:一边 top 看资源、一边 tail 看日志、一边跑命令。tmux 分屏可以一个窗口装下多个窗格,交互模式下用 Ctrl-b % 左右分屏、Ctrl-b " 上下分屏,Ctrl-b 加方向键在窗格间移动。

脚本化的分屏演示(同样真实执行):

tmux new -d -s work
tmux split-window -h    # 左右分:0.0 | 0.1
tmux split-window -v    # 再上下分:0.1 变成 0.1 / 0.2
tmux send-keys -t work:0.1 'watch -n 2 date' Enter
tmux list-panes -a

窗口分屏演示:三个窗格并列,list-panes 输出各窗格布局,其中一个窗格运行 watch 时钟

tmux list-panes -a 输出的每一行对应一个窗格,格式是 会话:窗口.窗格: [宽x高] [历史记录] %编号:上图中 work:0.0work:0.1work:0.2 三个窗格共存,(active) 标记当前激活窗格,最后一行是 0.1 窗格里 watch -n 2 date 正在刷新的系统时钟输出。

交互环境下分屏后,在每个窗格里独立跑命令,Ctrl-b z 可以临时把当前窗格最大化(再按一次还原),Ctrl-b x 关闭窗格。这套组合足以覆盖"一台显示器看多台机器/多个进程"的日常需求。

快捷键速查表

会话操作

快捷键 / 命令作用
Ctrl-b d分离当前会话(任务继续后台运行)
tmux ls列出所有会话
tmux attach -t 名称恢复指定会话
Ctrl-b s交互式会话列表,方向键选择切换
Ctrl-b $重命名当前会话
tmux kill-session -t 名称结束指定会话(任务终止)
tmux kill-server结束所有会话,重启后 tmux 进程清空

窗口操作(会话里的"标签页")

快捷键作用
Ctrl-b c新建窗口
Ctrl-b n / Ctrl-b p下一个 / 上一个窗口
Ctrl-b 0 ~ Ctrl-b 9按编号跳转窗口
Ctrl-b ,重命名当前窗口
Ctrl-b &关闭当前窗口(会提示确认)

窗格操作(窗口里的分屏)

快捷键作用
Ctrl-b %左右分屏
Ctrl-b "上下分屏
Ctrl-b 方向键在窗格间移动光标
Ctrl-b o按顺序循环切换窗格
Ctrl-b z当前窗格最大化 / 还原
Ctrl-b x关闭当前窗格
Ctrl-b !把当前窗格拆成独立窗口
Ctrl-b q显示窗格编号,按数字直接跳转

配置文件:让 tmux 更好用

tmux 的配置写在 ~/.tmux.conf(3.2 之后也支持 ~/.config/tmux/tmux.conf),改完用 tmux source-file ~/.tmux.conf 立即生效。推荐几行高频配置:

set -g mouse on            # 鼠标滚轮滚动、点击切换窗格、拖拽调整大小
set -g history-limit 50000 # 每个窗格的滚动缓冲区行数(默认 2000 太少)
set -g prefix C-a          # 把前缀键从 Ctrl-b 改成 Ctrl-a(与 screen 习惯一致,可选)
setw -g mode-keys vi       # 复制模式用 vi 键位(h/j/k/l 移动,更顺手)

其中 mouse onhistory-limit 是大多数人装完 tmux 的第一件事:前者让鼠标滚轮能回翻输出(默认滚轮无效),后者让你能翻看更多历史日志。

常见坑与排查

  • tmux lsno server running:说明当前用户下没有任何 tmux 服务。常见于刚重启、或会话里所有窗口都关闭后 tmux 自动退出(tmux 默认 exit-empty on,窗口全部关闭则服务端退出,属正常行为)。重开一个会话即可。
  • open terminal failed: not a terminal:attach 需要真实终端环境,在非交互 shell(如某些 CI、定时任务)里直接 attach 会报这个错,改用 tmux capture-pane -t 会话 -p 看输出。
  • 会话找不到但任务还在:tmux 的 socket 按用户隔离(/tmp/tmux-$UID/default),su 切了用户会看到不同的会话列表;多用户共用服务器时别用错账户。
  • 误杀了所有会话怎么办:tmux kill-server 会连坐所有会话,确认无运行中任务再执行;重要的长任务建议配合 nohup 或 systemd 兜底。

参考资料

发表评论

暂无评论,快来抢沙发吧!