终端窗口关闭、SSH 连接抖动或笔记本合盖,常常会把正在运行的构建、日志观察和远程编辑一起打断。tmux 的价值不在于把屏幕切成几块,而在于把程序运行的归属从一次 terminal client 连接中分离出来:client 可以离开,session 仍留在主机上。

tmux 是 terminal multiplexer,不是终端模拟器,也不是进程监督器。它运行在已有终端里,管理一组带 pseudo-terminal 的程序;它能抵抗 terminal 或网络连接中断,却不会让程序跨主机重启自动恢复。这个边界决定了 tmux 适合管理交互式工作台,不应被当成 systemd、容器编排器或备份系统的替代品。

先建立正确的对象关系

tmux server 管理 client、session、window 和 pane。client attach 到一个 session;session 维护 window 列表;window 由一个或多个 pane 组成;每个 pane 都承载一个 pseudo-terminal。window 还可以链接给多个 session,因此这不是一棵严格的 client 到 pane 的树。tmux(1) 手册对这组关系有正式定义。

flowchart LR
  T[已有终端] --> C[tmux client]
  C -->|attach| S[session: project]
  S --> W1[window: editor]
  S --> W2[window: logs]
  W1 --> P1[pane: shell]
  W1 --> P2[pane: test]
  W2 --> P3[pane: tail -f]
  SV[tmux server] -.管理.-> C
  SV -.管理.-> S
  SV -.管理.-> W1
  SV -.管理.-> W2

这张图回答一个常见疑问:断线后为什么任务还在。C-b d 只是让 client detach,server、session 和 pane 没有被销毁,pane 中的程序仍继续运行。反过来,kill-panekill-windowkill-sessionkill-server 会关闭对应范围的内容;主机重启也会结束这些进程。官方入门文档把 detach 描述为 client 离开外部终端、session 和程序留在后台运行,而不是持久化快照。Getting Started

五分钟建立第一个工作台

macOS 可以通过 Homebrew 安装:

1
2
brew install tmux
tmux -V

Homebrew 将 tmux 定义为 terminal multiplexer,并提供 brew install tmux 安装入口。Homebrew Formulae 在 Linux 上,使用发行版的软件包管理器安装同名包即可。

建立一个可反复进入的命名 session:

1
tmux new -A -s project

newnew-session 的别名,-s project 指定 session 名,-A 表示若 project 已存在则 attach,不存在才新建。这样不需要先执行 tmux ls 再判断是否创建。官方手册 将这个行为定义为 new-session -Aattach-session 处理已有的目标 session。

进入 tmux 后,默认前缀是 C-b,意思是按住 Ctrl 键再按 b,松开后再按后一枚按键。最小操作集只有六个:

目的 按键 结果
新建 window C-b c 为一个独立任务新建工作页
竖向切分 pane C-b % 左右并排
横向切分 pane C-b " 上下并排
切换 pane C-b + 方向键 或 C-b o 改变输入目标
临时离开 C-b d detach,程序继续运行
回到 session tmux attach -t project 重新 attach

一个可运行的起点是:把编辑器或交互 shell 放在左侧,把测试命令放在右侧;另开一个 logs window 持续观察日志。window 用来隔离会停留较久的任务,pane 用来并排放置需要同时观察的命令。不要把每条临时命令都切成 pane;一个 window 内超过三四个 pane 后,终端宽度会先成为瓶颈。

把工作单元划在正确的边界上

session、window 和 pane 的划分没有唯一答案,但边界一旦稳定,恢复成本会明显下降。

工作单元 适合承载的东西 命名建议 何时销毁
session 一个仓库、线上故障、一次远程主机工作 projectopsincident-42 工作目标结束
window editor、日志、数据库控制台、构建观察 codelogsdbwatch 子任务结束
pane 一组需要同时比较或彼此依赖的命令 不必强行命名 观察关系结束

这种划分可以概括为“持久对象放高层,并发观察放低层”:session 表示工作上下文,window 表示延续较久的职责,pane 表示当前视野。一个仓库一个 session、一个角色一个 window、一个观察关系一个 pane,比按工具类型把所有任务堆进同一 session 更容易重连和清理。

让新 pane 保持当前目录

默认切分后,新 pane 的工作目录未必符合当前任务。tmux 提供 pane_current_path format;官方 Recipes 用它为默认绑定补上 -c,让新 window 和 pane 继承当前 pane 的路径。Recipes

~/.tmux.conf 放入这组小配置:

1
2
3
4
5
6
7
8
9
set -g mouse on
set -g history-limit 100000
set -g renumber-windows on
set -g mode-keys vi
set -g status-keys vi

bind '"' split-window -c "#{pane_current_path}"
bind % split-window -h -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"

mouse on 允许鼠标选择、切换和调整;history-limit 决定每个 pane 保留的历史行数;renumber-windows on 会在 window 关闭后收拢编号。mode-keys vistatus-keys vi 只影响 copy mode 与命令提示符的按键表,不改变 shell 或编辑器的按键。Getting Started

配置文件会在 tmux server 启动时读取一次,而不是每建一个 session 就重新读取。修改后,在 tmux 内或普通 shell 中执行:

1
tmux source-file ~/.tmux.conf

这会加载大多数键绑定和选项。涉及 clipboard、TERM 或 terminal capability 的配置,官方 Clipboard 指南建议彻底重启 server 后再验证,因为外部终端能力会参与初始化。Clipboard

滚动、复制与系统剪贴板是三件事

C-b [ 进入 copy mode,可以查看 pane 的历史缓冲区;C-b ] 将 tmux 的 paste buffer 插入当前 pane。进入 copy mode 并不保证复制内容已经进入 macOS、Wayland、X11 或远程电脑的系统剪贴板。tmux(1) 手册 明确把 copy mode 的结果定义为 paste buffer。

系统剪贴板同步依赖外部 terminal 对 OSC 52 的支持、tmux 的 set-clipboard 选项,以及相关 terminfo capability。官方 Clipboard 文档还指出:set-clipboard on 允许在 pane 里输出文本的应用设置 tmux buffer 和外部剪贴板;运行不受信任命令时,这个权限要格外谨慎。Clipboard

先用两个检查确认环境,再考虑加入配置:

1
2
3
4
5
# tmux 外运行,确认外部终端类型
echo "$TERM"

# tmux 内运行,确认 OSC 52 capability
tmux info | grep 'Ms:'

远程 SSH 场景尤其不要假定本机 pbcopyxclipxsel 可以直接工作;这些工具通常只能连接其所在机器的本地剪贴板服务。OSC 52 可以跨 SSH 传递,但仍取决于 client terminal 是否允许。

远程主机上的正确用法

在远程主机登陆后,创建或进入远端 session:

1
2
ssh ops@example.net
tmux new -A -s ops

本地网络短暂中断时,远端 tmux server 仍在远端主机,ops session 里的命令继续执行。重新连接后再执行 tmux attach -t ops 即可恢复。session 归属的是运行 tmux server 的那台机器,不是本地 terminal,也不是 SSH client。

同一个 session 被多台 client 同时 attach 时,窗口尺寸和输入焦点需要额外约定。需要独占时可以使用:

1
tmux attach -d -t ops

-d 会 detach 其他已连到该 session 的 client。tmux(1) 手册 对多客户端窗口尺寸给出了 largestsmallestlatestmanual 策略;屏幕尺寸差异很大时,应先决定是否允许共同观察,再调整 window-size,不要把布局错乱误判为 tmux 丢失数据。Advanced Use

如果已经在本地 tmux 内,又进入远端 tmux,两个实例会竞争相同的前缀。默认情况下连续按两次 C-b,外层会把一个前缀发给内层;随后按内层命令键即可。不要把 unset $TMUX 当成常规解法:它绕开的是嵌套保护,不会解决“当前按键究竟交给哪一层”的问题。tmux 的示例配置会检测 TMUX 环境变量,正是为了对嵌套环境采取不同策略。example_tmux.conf

同步输入只适合可重复且无副作用的命令

tmux 可以在同一 window 内把输入送到多个 pane:

1
2
3
tmux set-window-option synchronize-panes on
# 执行只读检查,例如:hostname 或 git status
tmux set-window-option synchronize-panes off

这适合对多台测试机发送同一条只读诊断命令,也适合在多个环境里输入相同的临时查询。synchronize-panes 会把键入内容同步给同一 window 的其他非 mode pane,官方文档明确提醒要谨慎使用。Getting Started

不要在同步输入开启时执行 rm、部署、数据库写入、迁移或包含凭据的命令。先用 hostnamepwd 做一次可见的无副作用验证,再输入真正的命令;完成后立即关闭同步。批量操作的问题不是 tmux 是否能发送,而是目标集合和副作用是否已经被确认。

故障排查从对象边界开始

现象 先检查什么 常见原因
tmux attach 找不到 session tmux ls session 被 kill,或连到了另一台主机
断线后任务不见了 tmux ls、shell history、服务日志 任务未在 tmux 内启动,或 pane/window/session/server 已退出
新 pane 跑到错误目录 pwdtmux show-options -g 未使用 pane_current_path binding
复制不到系统剪贴板 tmux info | grep 'Ms:'、terminal 设置 OSC 52、terminal capability 或剪贴板策略不匹配
多客户端布局出现空白或裁切 tmux show-window-options window-size attached client 尺寸策略不适合当前场景

排查顺序保持一致:确认连接的是哪台主机,再确认 server 是否存在,然后检查 session、window 和 pane。这个顺序比从快捷键开始猜更快,因为 tmux 的大多数问题本质上是对象位置或生命周期判断错误。

速查:把工作流固化为三条命令

需求 命令或按键 采用的模式
进入一个稳定工作区 tmux new -A -s project 名称作为会话入口
暂时离开而不停止任务 C-b d client 与任务生命周期分离
恢复远程工作 tmux attach -t project 重新 attach 同一 session
新建相邻观察面 C-b %C-b " 并排观察,不拆分任务归属
让新 pane 跟随目录 -c "#{pane_current_path}" 上下文继承
批量执行同一条只读命令 临时开启 synchronize-panes 显式放大输入,立即关闭

稳定的 tmux 使用习惯不需要复杂主题或插件。命名 session、按职责建立 window、仅为并行观察切分 pane,并把 detach 当成连接动作而不是保存动作,就足以覆盖大多数本地开发和远程 SSH 场景。

参考资料

  1. tmux(1) 手册 — server、client、session、window、pane、copy mode 与 new-session 语义。
  2. tmux Wiki: Getting Started — 基础交互、detach、配置与选项。
  3. tmux Wiki: Advanced Use — working directory、window-size 和高级配置检查。
  4. tmux Wiki: FAQ — 多 client 尺寸、SSH agent 与常见边界。
  5. tmux Wiki: Recipes — 继承当前目录的 bindings。
  6. tmux Wiki: Clipboard — OSC 52、set-clipboard、外部工具和安全限制。
  7. tmux example configuration — 当前项目提供的配置范例。
  8. Homebrew Formulae: tmux — macOS 安装入口。