为什么需要 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 官方源( 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 attach、tmux 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 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
tmux list-panes -a 输出的每一行对应一个窗格,格式是 会话:窗口.窗格: [宽x高] [历史记录] %编号:上图中 work:0.0、work:0.1、work: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 on 和 history-limit 是大多数人装完 tmux 的第一件事:前者让鼠标滚轮能回翻输出(默认滚轮无效),后者让你能翻看更多历史日志。
常见坑与排查
tmux ls报no 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 兜底。
评论 (0)
暂无评论,快来抢沙发吧!