tmux
# tmux 终端复用器
Tmux 是一个终端复用器(terminal multiplexer),属于常用的开发工具。
为什么使用 tmux
- 保持会话不中断:即使 SSH 断开,任务也能继续运行,重连后可恢复。
- 多任务并行更高效:一个终端里可同时管理多个窗口和窗格。
- 远程开发更稳定:特别适合服务器运维、日志观察和长任务执行。
- 键盘操作流畅:减少鼠标切换成本,提升终端操作效率。
# 核心概念
tmux 的核心是三级嵌套结构:会话(Session) > 窗口(Window) > 窗格(Pane)。
- 1 个会话 = N 个窗口(一个项目可包含多个任务标签)
- 1 个窗口 = N 个窗格(一个任务标签可拆分多个并行终端)
- 窗格是 tmux 最小的执行单元,每个窗格对应一个独立的伪终端,可独立执行命令
前缀键(Prefix):tmux 所有快捷键都需要先按前缀键 Ctrl + b(下文简写为 Prefix),松开后再按功能键。
# Session(会话)
最顶层的独立工作区/项目容器,是进程与状态的持久化核心载体。
- 支持后台独立运行(detach),关闭终端、断开 SSH 均不影响会话内正在运行的任务
- 可随时重新接入(attach),一键恢复完整工作现场
- 不同会话的运行环境完全隔离,互不干扰
类比:一个独立的项目文件夹,或一间专属的工作房间。
# Window(窗口)
隶属于会话的全屏工作标签页,默认占据整个终端屏幕,是会话内的任务分类单元。
- 一个会话可创建多个窗口,支持快速切换(类似浏览器标签页)
- 每个窗口可进一步分割为多个窗格
- 窗口具有强依附性,仅属于某一个会话,会话关闭则其下所有窗口同步关闭
类比:浏览器的标签页,或工作房间里的一张桌子。
# Pane(窗格)
窗口内的分屏,是 tmux 最小的执行单元。
- 一个窗口可水平或垂直拆分为多个窗格,实现单屏幕多终端并行
- 每个窗格独立运行一个 shell,互不干扰
- 窗格关闭时,若窗口内只剩最后一个窗格,则窗口也关闭;若会话内只剩最后一个窗口,则会话也关闭
类比:桌子上划分出的多个工作区域。
# 命令与快捷键速查
# Session 管理
| 操作 | 命令 | 快捷键 |
|---|---|---|
| 查看所有会话 | tmux ls | — |
| 新建会话(命名) | tmux new -s <name> | — |
| 分离会话(后台保留) | tmux detach | Prefix d |
| 接入指定会话 | tmux attach -t <name> | — |
| 切换到其他会话 | tmux switch-client -t <name> | Prefix s(列表选择) |
| 切换到上一个会话 | — | Prefix L |
| 重命名会话 | tmux rename-session -t 0 <new> | Prefix $ |
| 杀死会话 | tmux kill-session -t <name> | — |
# Window 管理
| 操作 | 命令 | 快捷键 |
|---|---|---|
| 新建窗口 | tmux new-window -n <name> | Prefix c |
| 切换到上/下一个窗口 | — | Prefix p / Prefix n |
| 切换到指定编号窗口 | tmux select-window -t <num> | Prefix <number> |
| 从列表选择窗口 | — | Prefix w |
| 重命名窗口 | tmux rename-window <new> | Prefix , |
| 关闭窗口 | — | Prefix & |
| 移动当前窗口到指定编号 | tmux move-window -t <num> | Prefix .(弹出输入框) |
| 移动当前窗口到末尾 | tmux swap-window -t <末位编号> | — |
| 窗口重新连续编号 | tmux move-window -r | — |
| 移动当前窗口到其他 session | tmux move-window -t <session名>: | — |
窗口移动细节(实测 tmux 3.7c):
move-window -t <num>:目标编号已被占用时报错index in use,不会自动腾位;{end}不能作为移动目标(会被解析为已占用的末位编号)- 移到最后推荐
swap-window -t <末位编号>与末位窗口交换,编号保持连续;也可move-window -t 99(大空编号)排到最后,之后用move-window -r重排连续 - 跨 session 移动要求目标 session 已存在,否则报
can't find session;源窗口写法move-window -s <session>:<编号>
# Pane 管理
| 操作 | 命令 | 快捷键 |
|---|---|---|
| 左右分屏 | tmux split-window -h | Prefix % |
| 上下分屏 | tmux split-window | Prefix " |
| 切换焦点(循环) | tmux select-pane | Prefix o |
| 最大化/还原当前窗格 | — | Prefix z |
| 关闭当前窗格 | — | Ctrl + d 或 exit |
| 循环切换布局 | tmux select-layout even-vertical | Prefix Space |
| 上下高度均分 | tmux select-layout even-horizontal | Prefix Alt+1 |
| 左右宽度均分 | tmux select-layout even-vertical | Prefix Alt+2 |
| 上通栏下均分 | tmux select-layout main-horizontal(当前 pane 变顶部通栏) | Prefix Alt+3 |
| 左通栏右均分 | tmux select-layout main-vertical | Prefix Alt+4 |
| 平铺均分 | tmux select-layout tiled | Prefix Alt+5 |
| 窗格上移/下移 | tmux swap-pane -U / -D | — |
| 拆出为独立窗口 | — | Prefix ! |
| 合并回其他窗口 | Prefix : 后输入 join-pane -s <name> | — |
| 标记/取消标记窗格 | tmux select-pane -m | Prefix m |
| 设置窗格标题 | tmux select-pane -T <title> | — |
# 其他及帮助
| 操作 | 命令/快捷键 |
|---|---|
| 进入命令模式 | Prefix : |
| 查看所有快捷键 | tmux list-keys 或 Prefix ? |
| 列出所有命令 | tmux list-commands |
| 查看会话信息 | tmux info |
| 重新加载配置 | tmux source-file ~/.tmux.conf |
| 完整帮助 | man tmux |
在帮助界面(Prefix ?)中搜索:按 Ctrl + s 输入关键词 → Enter 确认 → n 下一个 / N 上一个 → q 退出。
查找特定类别的快捷键:
# 查找 window 相关快捷键并拷贝到剪贴板(macOS)
tmux list-keys | grep "bind-key.*-window" | pbcopy
2
# 复制与 Buffer 管理
tmux 的复制机制和普通终端不同:选中内容默认存入内建 Buffer 栈(buffer0 为最新),而非直接进系统剪贴板。设计哲学是鼓励全键盘操作(Prefix [ 进入 Copy Mode),实现跨会话、跨服务器的文本持久化。
# Buffer 操作
| 操作 | 快捷键/命令 |
|---|---|
| 进入复制模式 | Prefix [ |
| 粘贴最近一次缓存 | Prefix ] |
| 从列表选择并粘贴 | Prefix = |
| 查看 Buffer 列表 | Prefix # 或 Prefix :list-buffers |
| 粘贴指定编号缓存 | Prefix :paste-buffer -b 0 |
| 查看指定缓存内容 | Prefix :show-buffer -b 0 |
| 删除指定缓存 | Prefix :delete-buffer -b 0 |
# 复制模式(Copy Mode)导航
进入复制模式后,键位由 mode-keys 决定(vi 或 emacs,默认 emacs)。以下为 tmux 3.7 实测默认键位:
| 操作 | vi 模式 | emacs 模式 |
|---|---|---|
| 开始选中 | Space | Ctrl + Space |
| 矩形选择切换 | v | — |
| 复制并退出 | Enter | Alt + w |
| 上/下翻页 | Ctrl + b / Ctrl + f(或 PageUp / PageDown) | PageUp / PageDown |
| 半页上/下 | Ctrl + u / Ctrl + d | Alt + ↑ / Alt + ↓ |
| 跳到顶部/底部 | g / G | Alt + < / Alt + > |
| 行首/行尾 | 0 / $ | Ctrl + a / Ctrl + e |
| 搜索(向下/向上) | / / ? | Ctrl + s / Ctrl + r(增量) |
| 重复搜索/反向 | n / N | n / N |
| 退出不复制 | q 或 Escape | q 或 Escape |
注意:默认键位中 vi 模式没有
y(yank)绑定,需自行添加:bind -T copy-mode-vi y send-keys -X copy-selection-and-cancel。
# 鼠标拖选复制配置
开启 mouse on 后,tmux 会拦截所有鼠标事件,终端原生选择失效。配置以下内容可实现"鼠标拖选松开 → 自动复制到系统剪贴板":
# 开启鼠标支持
set -g mouse on
# 确保鼠标拖动可进入文本选择模式(不要 unbind,否则拖选失效)
bind -n MouseDrag1Pane copy-mode -M
# 鼠标拖选松开后自动复制到系统剪贴板(macOS)
# copy-mode 和 copy-mode-vi 两个表都要配,取决于 mode-keys 设置
bind -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
bind -T copy-mode MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "pbcopy"
2
3
4
5
6
7
8
9
10
关键细节:
copy-pipe-and-cancel后面必须接命令(如pbcopy),否则内容只进 tmux 内部 buffer,不进系统剪贴板mode-keys为vi时走copy-mode-vi表,为emacs(默认)时走copy-mode表,不确定就两个都配- Linux 用户将
pbcopy替换为xclip -selection clipboard或wl-copy(Wayland)
鼠标事件绑定辨析(不要混淆):
| 绑定名称 | 作用 |
|---|---|
MouseDrag1Border | 拖动边框调整窗格大小 |
MouseDrag1Pane | 在 pane 内拖动选择文本(绝对不要 unbind) |
常见踩坑:误以为
MouseDrag1Pane是"在窗格内拖动调整大小"而将其 unbind,导致鼠标拖选文本功能彻底失效。
临时绕过方案(不改配置时):macOS 按住 Option (⌥) 键选择;Linux/Windows 按住 Shift 键选择。
# 复制相关配置
# copy-mode 和选择 buffer 时使用 vi 键位
setw -g mode-keys vi
# 绑定为交互式选择 Buffer 模式(# 需加引号,否则被解释为注释)
bind-key "#" choose-buffer
bind-key "#" choose-buffer -Z # -Z 全屏显示
2
3
4
5
6
# 配置文件
配置文件默认位于 ~/.tmux.conf,但 tmux 并不绑定固定路径——配置可以指向任意位置的文件。修改后执行 tmux source ~/.tmux.conf 生效。
# 配置文件位置与自定义路径
指定配置文件的 4 种方式:
| 方式 | 命令/设置 | 说明 |
|---|---|---|
| 启动时指定 | tmux -f /任意路径/my.conf | 仅在 server 首次启动时读取;server 已在运行则被忽略 |
| 运行时加载 | tmux source-file /任意路径/my.conf | 立即生效,改配置后重载即用此方式 |
| 环境变量 | export TMUX_CONF=/任意路径/my.conf | tmux ≥ 3.4,覆盖默认查找路径 |
| 默认查找 | — | 不指定时:系统级 /etc/tmux.conf(存在则先加载)→ 用户级 ~/.tmux.conf → 不存在时回退 ~/.config/tmux/tmux.conf(tmux ≥ 3.1 的 XDG 路径) |
注意:-f 只在 server 启动那一刻读取一次,对已运行的会话不生效;要让改动应用到现有会话,用 source-file 重载。
# 基础配置
# 开启鼠标全能支持(点击、滚动、拖拽)
set -g mouse on
# 历史回滚行数
set -g history-limit 50000
# 启用 256 色
set -g default-terminal "screen-256color"
# 窗口和窗格从 1 开始编号(更顺手)
set -g base-index 1
set -g pane-base-index 1
# 快速重载配置:Prefix r
bind r source-file ~/.tmux.conf \; display "Config Reloaded!"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 分屏定制
# 分屏继承当前目录(保持原生键位)
bind '"' split-window -v -c "#{pane_current_path}" # 上下分屏,对应 Prefix "
bind % split-window -h -c "#{pane_current_path}" # 左右分屏,对应 Prefix %
bind c new-window -c "#{pane_current_path}" # 新建窗口也继承当前目录(可选)
# 自定义分屏快捷键(可选):v = 左右分屏(Vertical),h = 上下分屏(Horizontal)
bind v split-window -h -c "#{pane_current_path}"
bind h split-window -v -c "#{pane_current_path}"
2
3
4
5
6
7
8
# 状态栏定制
# 状态栏更新频率(秒)
set -g status-interval 60
# 定制右侧状态栏:#[fg=color] 是颜色标签,#(命令) 是执行脚本
set -g status-right-length 150
set -g status-right "#[fg=black] 🔋 AI Task: Coding... #[fg=yellow] | #(python3 ~/.tmux/energy_monitor.py) #[fg=white] | %H:%M "
2
3
4
5
6
# 自定义窗格布局
内置 preset(Prefix Space 循环切换的那几种)只有固定形状,"上 1 下 4"这类布局需要手动 split 拼出来。
# 案例:上 1 下 4 布局
┌──────────────────────────────┐
│ 1 │ 50% 高
├───────┬───────┬───────┬──────┤
│ 2 │ 3 │ 4 │ 5 │ 50% 高,4 列均分
└───────┴───────┴───────┴──────┘
2
3
4
5
一条命令创建(tmux 内执行):
tmux new-window \; split-window -v -p 50 \; split-window -h -p 75 \; split-window -h -p 67 \; split-window -h -p 50
百分比推导(-p 均相对被拆 pane):
-v -p 50:上下对半分-h -p 75:下侧第 1 刀,新 pane 拿 75%,原 pane 留 25%(第 1 列)-h -p 67:在 75% 上第 2 刀,新 pane 拿 67%×75%≈50%,原留 ≈25%(第 2 列)-h -p 50:剩余 50% 对半分(第 3、4 列)
整数百分比存在 ±0.1% 级误差,视觉上即均分。常用可绑快捷键(Prefix g):
bind g new-window \; split-window -v -p 50 \; split-window -h -p 75 \; split-window -h -p 67 \; split-window -h -p 50
# 模式化新建窗口(不破坏默认行为)
不想全局替换 Prefix c 影响所有新建场景,可保留其原生行为,另加"模式"入口按需选布局。
1. 模式定义脚本 ~/.tmux/mkwin(chmod +x;加/改模式只动这里):
#!/bin/sh
case "${1:-plain}" in
plain) tmux new-window ;;
14) tmux new-window \; split-window -v -p 50 \; split-window -h -p 75 \; split-window -h -p 67 \; split-window -h -p 50 ;;
12) tmux new-window \; split-window -v -p 50 \; split-window -h -p 50 ;;
2col) tmux new-window \; split-window -h -p 50 ;;
*) tmux new-window ;;
esac
2
3
4
5
6
7
8
2. ~/.tmux.conf 绑菜单键(Prefix G,大写不冲突默认键):
bind G display-menu -T "新建窗口模式" \
"1) 普通单pane" 1 "new-window" \
"2) 上1下4" 2 "run-shell '~/.tmux/mkwin 14'" \
"3) 上1下2" 3 "run-shell '~/.tmux/mkwin 12'" \
"4) 左右两列" 4 "run-shell '~/.tmux/mkwin 2col'"
2
3
4
5
Prefix c仍是原生普通新建,Prefix G弹菜单选布局- 脚本也可命令行直接调用:
~/.tmux/mkwin 14 - 嫌菜单多余可每种模式直接绑一个键;要继承当前目录,给
new-window/split-window加-c "#{pane_current_path}"
# split-window 语义细节
连续 split 时"哪个 pane 是新的"不靠猜,有三个固定机制:
- 方向固定:
-h新 pane 默认在右边,-v默认在下面;加-b才反转(新 pane 放到左/上) -p给的是新 pane:-h -p 75即新 pane 拿走被拆 pane 宽度的 75%,原 pane 留 25% 在左- 新 pane 自动成为 active(不加
-d时):链式命令里下一个不带-t的split-window作用的就是刚创建的新 pane,整条链靠此滚动,无需记编号
pane 编号语义:
pane_index(-t 0/1/2的数字)按布局位置(左上→右下)排列,split 后会重排,不是创建顺序- 真正稳定的身份是
pane_id(%0、%1…),创建后不变,跨 split/移动稳定
验证 pane 状态:
tmux list-panes -F '#{pane_index} id=#{pane_id} active=#{pane_active} w=#{pane_width}'
active=1 的即最近一次 split 出来的新 pane。
# 跨 Window 批量整理 Pane(把多个 pane 移到新 window)
场景:当前 window 里的 pane 2、6、7 同属一件事(如某个需求/项目的并行任务),要整体搬到名为 <name> 的新 window。用 break-pane(pane 拆成新 window)+ join-pane(pane 移入已有 window)组合完成:
# 0. 先确认编号(pane_index 按布局位置排列,见下方"关键原理")
tmux list-panes -F '#{pane_index} id=#{pane_id} #{pane_current_command}'
# 1. 记录当前 session:window
CUR=$(tmux display-message -p '#S:#I')
# 2. 把 pane 7 拆成新 window 并命名(-d 不跳焦点;-P -F '#I' 输出新窗口编号)
NEW=$(tmux break-pane -d -n "<name>" -P -F '#I' -t "$CUR.7")
# 3. 从大到小移入 pane 6、2(顺序原因见下)
tmux join-pane -s "$CUR.6" -t ":$NEW"
tmux join-pane -s "$CUR.2" -t ":$NEW"
# 4. 整理布局 + 锁定窗口名(防止 automatic-rename 按 pane 内程序改掉名字)
tmux select-layout -t ":$NEW" tiled
tmux set-option -w -t ":$NEW" automatic-rename off
# 验证:新 window 应有 3 个 pane
tmux list-windows -F '#{window_index} "#{window_name}" panes=#{window_panes}'
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
关键原理(实测 tmux 3.7c):
pane_index是布局位置索引,移走一个 pane 后其余 pane 立即重编号(填补空缺)。按编号操作必须从大到小(7 → 6 → 2):先移走最大编号不影响小编号;若先移 2,原 6、7 会漂移成 5、6,导致移错 pane- 更稳的替代:改用
pane_id(%0、%1…,终身不变)。先list-panes查出 2/6/7 对应的%id,再以-t '%42'、-s '%37'操作,与顺序无关 - 用
break-pane -n起头而非new-window:后者会自带一个多余空 pane,最后还得kill-pane;break-pane让目标 pane 直接成为新 window 的第一个 pane join-pane -s <源 pane> -t <目标 window>:移入后布局可能不均,select-layout tiled(或Prefix Space循环)重新整理;:3中的:表示当前 session- 以上命令在 tmux 内的 pane 中执行;
Prefix !是 break-pane 的交互版(拆当前 pane),Prefix :后输入 join-pane 命令是其交互入口
# 窗格定制:命名、边框与级别配色
tmux 支持给窗格命名、定制边框颜色,甚至为单个窗格单独配色。per-pane 配色本质是 pane option,用 set -p 设置(实测 tmux 3.7c)。
# Pane 命名(标题)
窗格默认没有名字,可通过标题机制命名并显示在边框上:
# 设置当前窗格标题
tmux select-pane -T "日志"
# 在边框上显示标题行(off/top/bottom,默认 off)
tmux set pane-border-status top
# 标题行的显示格式(可自定义)
tmux set pane-border-format " #[bold]#{pane_title} "
2
3
4
5
6
7
8
交互式命名可绑快捷键(Prefix T):
bind T command-prompt -p "pane name:" "select-pane -T '%%'"
# 边框颜色(全局)
全局配置按"活动/非活动"两类区分边框颜色:
set -g pane-border-style fg=green # 非活动窗格边框
set -g pane-active-border-style fg=yellow # 活动窗格边框(可加 bg=black)
2
边框线型(tmux ≥ 3.2):set -g pane-border-lines heavy(可选 single/double/heavy/simple)。
# 单个 Pane 独立配色
全局配置只能区分活动/非活动两组。要给某个窗格单独指定颜色,把样式作为 pane option 用 set -p 设置:
# 当前窗格边框单独设色(active/inactive 两个都设,焦点离开后颜色才不变)
tmux set -p pane-active-border-style 'fg=colour196'
tmux set -p pane-border-style 'fg=colour196'
# 定位到指定窗格设色(-t 格式:会话:窗口.窗格)
tmux set -p -t 0:1.1 pane-active-border-style 'fg=cyan'
# 窗格内容(文字/背景)单独设色
tmux set -p window-style 'fg=red' # 文字颜色
tmux set -p window-style 'bg=colour237' # 背景颜色
# 清除单独配色,恢复继承全局(内容样式必须两个都清,见下方说明)
tmux set -up pane-active-border-style
tmux set -up pane-border-style
tmux set -up window-style
tmux set -up window-active-style
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
pane-active-border-style/pane-border-style/window-style/window-active-style均可按窗格设置,set -p只作用于目标窗格,优先级高于全局值;set -up取消后恢复继承- 内容样式清理必须成对:
window-style(非活动时生效)和window-active-style(活动时生效)是两个独立选项,只清一个会出现"清了还是红的"——活动窗格实际渲染用的是window-active-style - 排查哪个窗格被误设(扫描所有会话,输出 pane option 非空的窗格):
tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_id}' | \
while read -r t id; do
s=$(tmux show -p -t "$t" window-style 2>/dev/null)
a=$(tmux show -p -t "$t" window-active-style 2>/dev/null)
[ -n "$s$a" ] && echo "$t ($id) => [$s] [$a]"
done
2
3
4
5
6
- 快捷键绑定中
set -p不带-t即作用于当前窗格;命令行调用时不带-t会落到"当前客户端"的活动窗格,注意目标 - 新建窗格时可直接带样式:
split-window -S 'fg=colour196' -R 'fg=colour196'(-S活动边框、-R非活动边框、-s内容样式)
旧教程陷阱(实测 tmux 3.7c):tmux 3.2/3.3 时代的 select-pane -P(边框)/ -p(内容)已被移除——-p 直接报 unknown flag -p;-P 仍能执行但实际同时设置内容样式 window-style 和 window-active-style(文字变色)而非边框,且 man 手册已不记载,不要再用。误用后按上面"成对清理"的方式恢复。
# 级别配色方案(按优先级标记窗格)
多窗格并行场景(调试、构建、日志监控同时进行),可给窗格按重要级别打标,注意力分配一眼可辨:
| 级别 | 配色 | 适用场景 |
|---|---|---|
| P1 | 红色 colour196 | 最高优先级:线上排查、调试核心 |
| P2 | 橙色 colour208 | 中等:构建/测试/长任务 |
| P3 | 绿色 colour46 | 低:日志/监控,扫一眼即可 |
# ===== Pane 级别配色(Prefix F1~F4)=====
set -g pane-border-status top
set -g pane-border-format ' #{pane_index}:#{pane_title} '
bind F1 select-pane -T 'P1-核心' \; set -p pane-active-border-style 'fg=colour196' \; set -p pane-border-style 'fg=colour196'
bind F2 select-pane -T 'P2-进行中' \; set -p pane-active-border-style 'fg=colour208' \; set -p pane-border-style 'fg=colour208'
bind F3 select-pane -T 'P3-参考' \; set -p pane-active-border-style 'fg=colour46' \; set -p pane-border-style 'fg=colour46'
bind F4 select-pane -T '' \; set -up pane-active-border-style \; set -up pane-border-style
2
3
4
5
6
7
8
用法:Prefix F1/F2/F3 给当前窗格打级别,边框立即变色,标题栏同步显示 P1-核心 等标记;Prefix F4 清除级别恢复默认。
键位选择注意:不要绑 Prefix 1/2/3,与"切换到指定编号窗口"冲突;F1–F4 无冲突。备选键位:
bind -n M-1:免 Prefix 直接Alt+1(注意某些 TUI 程序会占用 Alt+数字)bind !/bind @:Prefix Shift+1/2(#已被choose-buffer占用,见「复制相关配置」)
# 格式变量(Format Variables)
tmux 配置中以 # 开头的特殊占位符,用于动态提取当前会话或窗口的信息(如 #{pane_current_path})。完整列表见 man tmux 搜索 /FORMATS,或 tmux Wiki - Formats (opens new window)。
# 插件与配套工具
# TPM 插件管理器
TPM(Tmux Plugin Manager)是 tmux 的插件管理器。
# 安装 TPM
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
2
在 ~/.tmux.conf 底部添加:
# 声明插件管理器本身
set -g @plugin 'tmux-plugins/tpm'
# 初始化 TPM(这行必须放在配置文件的最底部)
run '~/.tmux/plugins/tpm/tpm'
2
3
4
5
安装插件:tmux source ~/.tmux.conf 后按 Prefix I(大写 i)。
# tmux-resurrect(会话持久化)
默认 tmux 不支持持久化,所有会话信息保存在内存中的 tmux server 进程里,重启后丢失。tmux-resurrect 可保存/恢复所有会话、窗口、窗格、布局、目录和运行程序。
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'
# 启用自动恢复(重启后第一次打开 tmux 自动加载上次保存的布局)
set -g @continuum-restore 'on'
2
3
4
5
- 手动保存:
Prefix + Ctrl + s - 手动恢复:
Prefix + Ctrl + r - 保存目录:
~/.tmux/resurrect/
# tmuxp(配置文件式工作区)
用 YAML 定义固定工作区,每次一键加载,适合项目化场景。
pip install tmuxp
示例 workspace.yaml:
session_name: dev
windows:
- window_name: editor
layout: main-horizontal
panes:
- shell_command: [cd ~/code, vim]
- shell_command: [cd ~/code, npm run dev]
- window_name: logs
panes:
- shell_command: [tail -f /var/log/syslog]
2
3
4
5
6
7
8
9
10
使用:tmuxp load workspace.yaml
# 常见问题排查
通用注意:配置修改后执行
tmux source ~/.tmux.conf生效。若曾在运行时执行过unbind,仅source不会自动恢复被解绑的默认绑定,需手动bind回来或重启 tmux server(tmux kill-server)。
# 鼠标滚动导致整个界面位移
现象:在 tmux 分屏状态下,滚动鼠标会导致整个终端界面(包括分屏线和所有窗格)像网页一样整体位移,无法正常查看上方历史日志。
原因:终端软件拦截了滚动信号,滚动的是自身的"回滚缓冲区",而不是将信号传递给 tmux 内部处理。
解决方案:
# 1. 开启鼠标模式
set -g mouse on
# 2. 拦截滚轮信号:确保滚动只触发"进入复制模式并翻页"
# -e 表示若 pane 已在底部(无更多历史),则不进入 copy-mode(tmux 3.2+)
# 只需绑定 WheelUpPane,进入 copy-mode 后滚轮向下由 copy-mode 自行处理
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -F '#{pane_in_mode}' 'send-keys -M' 'copy-mode -e'"
2
3
4
5
6
7
iTerm2 进阶设置(macOS):Settings → Advanced → 搜索 Scroll → 将 "Scroll wheel sends arrow keys in alternate screen mode" 设为 Yes。
验证:执行 tmux source ~/.tmux.conf 并重启终端。滚动时观察右侧系统滚动条是否不动,且当前窗格右上角出现 [0/xxx] 翻页字样。
- 退出滚动模式:按
q或Enter - 强制滚动终端本身缓冲区:按住
Option(macOS)或Shift(Linux)再滚动
# 鼠标拖选后高亮立即消失,系统剪贴板无内容
原因:MouseDragEnd1Pane 绑定的复制命令没有正确将内容送到系统剪贴板,常见两种情况:
- 绑定的是
copy-selection-and-cancel(无管道),内容只进 tmux 内部 buffer,不进系统剪贴板 copy-pipe-and-cancel后接的命令执行失败(如 Linux 上误用了 macOS 的pbcopy)
解决:确保绑定 copy-pipe-and-cancel 并接上正确的系统剪贴板命令,见「复制与 Buffer 管理 → 鼠标拖选复制配置」。Linux 用户将 pbcopy 替换为 xclip -selection clipboard 或 wl-copy(Wayland)。
# 鼠标拖选完全没反应
原因:root 表中的 MouseDrag1Pane 被意外 unbind 了,导致拖动鼠标不会进入 copy-mode。
排查:
tmux list-keys -T root | grep MouseDrag1Pane
解决:
tmux bind -n MouseDrag1Pane copy-mode -M
# 想保留选中高亮,手动确认后再复制
取消 MouseDragEnd1Pane 的自动复制行为,松开鼠标后停留在复制模式,手动确认后再复制:
unbind -T copy-mode-vi MouseDragEnd1Pane
unbind -T copy-mode MouseDragEnd1Pane
2
手动复制操作(完整键位见「复制模式(Copy Mode)导航」):
- vi 模式(
mode-keys vi):选中后按Enter复制并退出(默认无y键,可按该节说明自行绑定) - emacs 模式(默认):选中后按
Alt + w复制并退出 - 不复制直接退出:按
q或Escape
以上三个复制相关问题可按顺序排查:先确认
MouseDrag1Pane存在(能选中文本)→ 再确认MouseDragEnd1Pane绑定了正确的copy-pipe-and-cancel(能进系统剪贴板)→ 最后根据需求决定是否保留高亮手动复制。