终端复用 tmux
Linux 运维基础 · 第十章 目标:掌握 tmux 核心操作,让 SSH 会话不再因断线而丢失
1. 概述#
你是否遇到过这种场景:
- SSH 到服务器跑一个 2 小时的脚本,跑到一半 VPN 断了
- 四个终端窗口切来切去,分不清哪台是哪台
- 想同时看两台服务器的日志,只能开多个 SSH 窗口
tmux(Terminal MUltipleXer)解决的就是这些问题。它在服务器端维护会话,你的本地终端只是"窗口"——断线了,会话还在服务器上跑,重新连上就能恢复。
2. 为什么要用 tmux#
| 场景 | 不用 tmux | 用 tmux |
|---|---|---|
| SSH 断线 | 正在跑的任务直接死掉 | 重新 attach,一切都在 |
| 多任务并行 | 开多个 SSH 窗口,来回切 | 一个窗口内分屏操作 |
| 恢复工作环境 | 每次登录从零开始 | attach 后恢复上次所有面板 |
| 结对排障 | 截屏发来发去 | 双方 attach 同一会话,实时看同一屏幕 |
| 长时间任务 | 不敢关终端,不敢合笔记本 | detach 后走人,回来再 attach |
3. 三层结构#
tmux 有三层嵌套结构:
text
Session(会话)
├── Window 0(窗口 0)── 相当于浏览器的一个标签页
│ ├── Pane 0(面板 0)── 一块划分好的区域
│ └── Pane 1(面板 1)
├── Window 1(窗口 1)
│ └── Pane 0
└── Window 2(窗口 2)
├── Pane 0
└── Pane 1| 层级 | 概念 | 类比 |
|---|---|---|
| Session | 一个完整的"工作台" | 项目文件夹 |
| Window | 会话中的一个全屏页面 | 编辑器的一个标签 |
| Pane | 窗口中的分屏区域 | 把一个标签页竖着或横着切开 |
4. 核心操作#
4.1 会话管理#
bash
# 创建新会话
tmux # 创建,自动编号
tmux new -s deploy # 创建并命名(推荐)
# 列出所有会话
tmux ls # tmux list-sessions 的缩写
# Attach:重新连接已有会话
tmux a # 连接最新的会话
tmux a -t deploy # 连接名为 deploy 的会话
# 在已 attach 的状态下,detach(离开但保持会话运行)
# 快捷键:Ctrl+b d
# 杀死会话
tmux kill-session -t deploy # 在 tmux 外杀
# 在 tmux 内:Ctrl+b :kill-session4.2 前缀键:Ctrl+b#
tmux 所有操作都要先按 Ctrl+b(默认前缀键),再按对应的命令键。
两步操作:先按 Ctrl+b 松开,再按目标键。
4.3 窗口(Window)操作#
| 快捷键 | 功能 |
|---|---|
Ctrl+b c | 创建新窗口 |
Ctrl+b , | 重命名当前窗口(会提示输入新名字) |
Ctrl+b & | 关闭当前窗口(会确认) |
Ctrl+b n | 下一个窗口 |
Ctrl+b p | 上一个窗口 |
Ctrl+b 数字 | 跳转到第 N 个窗口(Ctrl+b 0, Ctrl+b 1...) |
Ctrl+b w | 从列表中选择窗口 |
Ctrl+b f | 按名称搜索窗口 |
4.4 面板(Pane)操作#
| 快捷键 | 功能 |
|---|---|
Ctrl+b " | 横分面板(上下分) |
Ctrl+b % | 竖分面板(左右分) |
Ctrl+b 方向键 | 切换面板 |
Ctrl+b x | 关闭当前面板(会确认) |
Ctrl+b 空格 | 循环切换面板布局 |
Ctrl+b { | 当前面板与上一个互换 |
Ctrl+b } | 当前面板与下一个互换 |
Ctrl+b z | 当前面板全屏 / 恢复原大小 |
Ctrl+b Ctrl+方向键 | 调整面板大小(按住 Ctrl) |
4.5 滚动和复制#
bash
# 进入复制/滚动模式(查看历史输出)
Ctrl+b [
# 在这个模式下:
# 方向键 / PageUp / PageDown 滚动
# Ctrl+b PageUp 整页上翻
# q 退出滚动模式
# 如果你熟悉 vim,可以启用 vi 模式(见下方配置)5. 配置文件 ~/.tmux.conf#
5.1 一个实用的配置#
bash
# ~/.tmux.conf
# 把前缀键从 Ctrl+b 改为 Ctrl+a(GNU Screen 风格,更顺手)
unbind C-b
set -g prefix C-a
bind C-a send-prefix
# 允许鼠标操作(点击面板、拖动分割线、滚轮翻页)
set -g mouse on
# 把分屏快捷键改得更直观
bind | split-window -h -c "#{pane_current_path}" # Ctrl+a | 竖分
bind - split-window -v -c "#{pane_current_path}" # Ctrl+a - 横分
# 新面板/窗口继承当前目录
bind c new-window -c "#{pane_current_path}"
# vi 风格的复制模式
setw -g mode-keys vi
# 状态栏美化
set -g status-bg colour235
set -g status-fg white
set -g status-left '#[fg=green]#S '
set -g status-right '#[fg=yellow] %H:%M %d-%b-%y'
# 增大历史缓冲区
set -g history-limit 500005.2 使配置生效#
bash
# 新创建的会话自动生效
# 已有会话需要手动加载
tmux source-file ~/.tmux.conf
# 或
Ctrl+b :source-file ~/.tmux.conf6. 进阶技巧#
6.1 复制、粘贴与系统剪贴板#
bash
# 进入复制模式
Ctrl+b [
# vi 模式下(需 setw -g mode-keys vi):
# 空格键 开始选择
# 移动 选择区域
# Enter 复制到 tmux 内部缓冲区并退出
# 在 tmux 内粘贴自己的缓冲区
Ctrl+b ]重点澄清:上面的
Enter/Ctrl+b ]走的是 tmux 自己的缓冲区,默认不会进你本机的系统剪贴板(Ctrl+V 粘不出来)。要打通系统剪贴板有两条路:bash# 路 1(推荐):让 tmux 用 OSC52 写终端剪贴板,SSH 场景也能同步到本地 set -g set-clipboard on # 写进 ~/.tmux.conf;需终端支持 OSC52(现代终端多数支持) # 路 2:本地有图形环境时,把选区管到 xclip/wl-copy(Wayland)/pbcopy(macOS) bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -sel clip'
6.2 同步多个面板的输入#
bash
# 场景:同时对 3 台服务器执行相同命令
# 1. 创建三个面板
# 2. 分别 SSH 到三台服务器
# 3. 开启同步输入:
Ctrl+b :setw synchronize-panes on
# 现在在任何面板的输入都会同步到所有面板
# 完成后关闭:
Ctrl+b :setw synchronize-panes off6.3 脚本化启动 tmux 工作区#
bash
#!/bin/bash
# 自动创建 tmux 会话并分屏
SESSION="devops"
# 如果会话已存在,attach
if tmux has-session -t "$SESSION" 2>/dev/null; then
tmux attach -t "$SESSION"
exit 0
fi
# 创建新会话
tmux new-session -d -s "$SESSION" -n "logs"
# 创建日志面板
tmux send-keys -t "$SESSION:logs" "cd /var/log/myapp" Enter
tmux send-keys -t "$SESSION:logs" "tail -f app.log" Enter
# 横分一个新面板,看错误日志
tmux split-window -v -t "$SESSION:logs"
tmux send-keys -t "$SESSION:logs.1" "tail -f /var/log/nginx/error.log" Enter
# 新建窗口看监控
tmux new-window -t "$SESSION" -n "monitor"
tmux send-keys -t "$SESSION:monitor" "htop" Enter
# 竖分看网络
tmux split-window -h -t "$SESSION:monitor"
tmux send-keys -t "$SESSION:monitor.1" "watch -n1 'ss -tan'" Enter
# 回到第一个窗口
tmux select-window -t "$SESSION:logs"
# attach
tmux attach -t "$SESSION"7. 实战场景#
实战 1:部署会话不丢失#
bash
# 场景:晚上 10 点在家帮公司部署新版本,但公司 VPN 不稳定
# 1. SSH 到服务器后先建 tmux 会话
tmux new -s deploy_20250701
# 2. 执行部署(在 tmux 内)
./deploy.sh
# 3. 如果 VPN 断了、SSH 断了...
# 不用担心,重新 SSH 上去:
tmux a -t deploy_20250701
# 一切都在,部署还在继续跑
# 4. 完成后清理
tmux kill-session -t deploy_20250701实战 2:同时监控多个日志#
bash
# 创建监控会话
tmux new -s monitor
# Ctrl+b % 竖分 → 左边看 app 日志
tail -f /var/log/myapp/app.log | grep -i error
# Ctrl+b 方向键 → 切到右边
# Ctrl+b " 横分 → 右边上:系统日志
tail -f /var/log/syslog | grep -i "out of memory"
# 切到右边下
# Ctrl+b " 横分 → 右边下:top
top
# 按 Ctrl+b d detach,日志继续实时跟踪
# 随时 tmux a -t monitor 回来实战 3:三台服务器同时操作#
bash
tmux new -s multicloud
# Ctrl+b " 再 Ctrl+b " → 三个面板
# 在每个面板 SSH 到不同服务器
# 面板 0: ssh web-01
# 面板 1: ssh web-02
# 面板 2: ssh web-03
# 开启同步(在同步每个命令前会发到所有面板)
Ctrl+b :setw synchronize-panes on
# 现在上中下三个面板输入完全同步
uptime # 同时看三台服务器负载
df -h # 同时看三台磁盘
# 注意:打错命令也会同步到三台,小心!8. 对比 screen#
tmux 的前辈是 GNU Screen。如果只能选一个,选 tmux。
| 特性 | tmux | screen |
|---|---|---|
| 分屏 | 原生支持,横分竖分灵活 | 需要打补丁 |
| 客户端分离 | 更稳健 | 偶尔有 bug |
| 配置 | 更清晰 | 较复杂 |
| 活跃度 | 社区活跃,持续更新 | 更新缓慢 |
| 默认快捷键 | Ctrl+b | Ctrl+a |
9. 小结#
| 知识点 | 一句话记忆 |
|---|---|
| 三层结构 | Session > Window > Pane |
| 会话 | tmux new -s name 创建,tmux a -t name 恢复,Ctrl+b d 离开 |
| 窗口 | Ctrl+b c 新建,Ctrl+b n/p 切换,Ctrl+b 数字 直达 |
| 面板 | Ctrl+b " 横分,Ctrl+b % 竖分,Ctrl+b 方向键 切换 |
| ~/.tmux.conf | 改前缀键、开鼠标支持、设 vi 模式、美化状态栏 |
| 本质 | tmux 在服务器端维护会话,终端只是"显示窗口"——断线不怕 |