终端复用组件——tmux

cuixiaogang

概述

tmux(Terminal Multiplexer,终端复用器)是一个开源的终端复用工具,用C语言编写,采用客户端-服务器架构。它能在一个终端窗口里管理多个相互独立的会话、窗口和窗格,并支持把会话放到后台持续运行,断开连接后再随时恢复。

普通终端有两个痛点:一是一个窗口只能跑一个 shell,要同时看日志、编辑代码、跑命令就得开一堆终端窗口来回切;二是 SSH 连到远程服务器后,一旦网络断开或关掉终端,正在跑的进程就跟着挂了。tmux 把这两件事一起解决了——一个窗口里随意分屏,会话还能脱离终端在后台活着。

应用场景

  • 远程开发不怕断线:SSH 到服务器上开 tmux 会话跑任务,网络断了进程照样在后台跑,重连后tmux attach接回现场
  • 一屏多用:左边编辑代码、右上跑服务、右下看日志,无需来回切窗口
  • 长任务托管:跑数据迁移、编译、训练这类耗时任务,分离会话让它自己跑,不必守着终端
  • 固定工作区:把一个项目常用的几个窗格布局固定下来,每次进来就是熟悉的环境

核心优势

  • 会话持久化:进程与终端解耦,关掉终端甚至断开 SSH,会话依然在服务器上运行
  • 灵活分屏:单窗口内任意水平/垂直分割成多个窗格,每个窗格是独立的 shell
  • 纯键盘操作:全部操作走快捷键,手不离键盘,配合 Vim 类工具很顺手
  • 高度可配置:通过.tmux.conf自定义前缀键、快捷键、状态栏、配色等

核心概念

为什么需要终端复用

要理解 tmux,先理解它解决的隔离问题。普通 SSH 会话里,你的 shell 进程是终端的子进程,终端一关,进程收到挂断信号(SIGHUP)就被杀掉。tmux 的做法是:真正跑活儿的 shell 由后台的 tmux 服务器托管,你的终端只是一个连上去的客户端。客户端断开,服务器和它管理的进程毫发无伤,下次再连个客户端上来就行。这就是会话能”持久化”的根本原因。

三层模型

tmux 的组织结构是清晰的三层,从大到小是 会话(session)→ 窗口(window)→ 窗格(pane)。理解这三层是用好 tmux 的关键。

层级 英文 类比 说明
会话 session 一个项目工作区 最顶层容器,可后台持续运行。通常一个项目/任务开一个会话
窗口 window 浏览器的标签页 会话内的标签页,一个会话可有多个窗口,同时刻只显示一个
窗格 pane 标签页内的分屏 窗口内的分割区域,每个窗格是一个独立的 shell,可并排显示

一个会话里可以有多个窗口(像浏览器的多个标签页),每个窗口又可以切分成多个窗格(像把一块屏幕拆成几格)。会话在最外层,它能脱离终端在后台活着;窗口和窗格则是会话内部的组织方式。

1
2
3
4
5
6
session(会话,可后台运行)
├── window 0(窗口,标签页)
│ ├── pane(窗格,独立 shell)
│ └── pane(窗格,独立 shell)
└── window 1(窗口,标签页)
└── pane(窗格,独立 shell)

前缀键

tmux 的几乎所有快捷键都要先按 前缀键(prefix) 唤起,再按功能键。默认前缀键是 Ctrl+b(下文统一记作 C-b)。

比如“垂直分割窗格”的操作是 C-b %,意思是:先同时按下 Ctrlb,松开,再按 %。前缀键的存在是为了不和 shell、Vim 等程序自身的快捷键冲突——只有先按了前缀,后面的键才被 tmux 截获。

C-b 离得有点远、不好按,很多人会把它改成 C-a(screen 的默认前缀),改法见后文配置一节。

tmux 与 screen 的对比

终端复用器里最常被拿来比较的就是 GNU screen 和 tmux,两者功能定位重合。screen 更老、几乎所有系统自带;tmux 更新、设计更现代,是目前的主流选择。screen的使用方法详见《终端复用工具——screen》

对比项 screen tmux
诞生时间 1987 年,更老牌 2007 年,更现代
默认前缀键 C-a C-b
窗格分割 支持,但较弱、配置繁琐 原生支持,水平/垂直都方便
配置文件 .screenrc,语法较晦涩 .tmux.conf,更直观易读
状态栏 简单 可高度自定义,信息丰富
客户端-服务器 是,多客户端可共享同一会话
脚本化/可控性 较弱 强,命令体系完整
维护活跃度 维护较少 活跃,持续更新

新项目建议直接上 tmux,分屏、状态栏、可配置性、维护活跃度全面占优;只有在某些只能用自带工具、且系统仅预装 screen 的老环境里,才退而用 screen。两者不能混用一套快捷键,但概念是相通的,会一个学另一个很快。

安装与使用

安装

tmux 在主流系统的包管理器里都有,直接装即可。

1
2
3
4
5
6
7
8
# Debian / Ubuntu
apt install tmux

# CentOS / RHEL
yum install tmux

# macOS(Homebrew)
brew install tmux

装完用 tmux -V 查看版本。

会话管理

会话是最外层、也是 tmux 持久化能力的载体。下面这组操作覆盖会话的整个生命周期。

操作 命令 / 快捷键 说明
新建匿名会话 tmux 直接进入一个新会话,名字是数字编号
新建命名会话 tmux new -s 名字 起名便于区分,强烈建议
分离当前会话 C-b d detach,退回普通终端,会话转入后台继续运行
列出所有会话 tmux ls 等价于 tmux list-sessions
接回会话 tmux attach -t 名字 attach,可简写 tmux a -t 名字,不带 -t 接回最近一个
切换会话 C-b s 列出所有会话,光标选择后切换
重命名会话 C-b $ 重命名当前会话
关闭会话 tmux kill-session -t 名字 彻底结束指定会话
关闭所有会话 tmux kill-server 结束 tmux 服务器,所有会话一起销毁

这里最核心的是”分离(detach)“和”接回(attach)“这对操作,它俩是 tmux 持久化的关键:

1
2
3
4
5
6
7
8
# 在服务器上开一个会话跑长任务
tmux new -s deploy

# 任务跑起来后,按 C-b d 分离,会话转入后台
# 此时可以安全关掉终端、断开 SSH

# 过会儿重新连上服务器,接回现场
tmux attach -t deploy

注意区分”分离”和”关闭”:分离(C-b d)只是离开,会话还在后台跑;关闭(kill-session)才是真正结束。在会话里把所有 shell 都 exit 掉,会话也会随之消失。

窗口管理

窗口是会话内部的标签页。窗口操作都要先按前缀键 C-b

操作 快捷键 说明
新建窗口 C-b c create,新窗口成为当前窗口
下一个窗口 C-b n next
上一个窗口 C-b p previous
按编号切换 C-b 数字 C-b 0 跳到 0 号窗口
窗口列表选择 C-b w 列出所有窗口,光标选择
重命名窗口 C-b , 给当前窗口改名,方便辨认
关闭窗口 C-b & 会弹出确认,关闭当前整个窗口

底部状态栏会列出当前会话的所有窗口(如 0:bash 1:vim*),带 * 的是当前窗口。给窗口起个有意义的名字(C-b ,)能让状态栏一目了然。

窗格管理

窗格是把一个窗口切成的多个独立区域,每格一个 shell,这是 tmux 用得最爽的功能。窗格操作同样先按 C-b

操作 快捷键 说明
垂直分割 C-b % 左右切成两个窗格
水平分割 C-b " 上下切成两个窗格
在窗格间切换 C-b 方向键 朝上下左右移动到相邻窗格
切到下一个窗格 C-b o 顺序循环切换
显示窗格编号 C-b q 短暂显示编号,期间按数字可跳转
调整窗格大小 C-b 按住方向键 按住前缀后用方向键改大小
切换布局 C-b 空格 在几种预设布局间循环
当前窗格全屏 C-b z zoom,临时放大占满窗口,再按一次还原
把窗格转为窗口 C-b ! 将当前窗格独立成一个新窗口
关闭当前窗格 C-b x 弹确认后关闭,或直接在该 shell 里 exit

记忆小窍门:分割键 % 是竖线形状对应垂直分割(左右分)," 是横向排列对应水平分割(上下分)。C-b z 的全屏切换非常实用——某个窗格要专注操作时放大,弄完再缩回,布局不乱。

配置文件

tmux 的默认行为可以通过用户主目录下的 ~/.tmux.conf 自定义。改完后让配置生效有两种方式:重开 tmux,或在已有会话里执行 C-b : 进入命令行后输入 source-file ~/.tmux.conf

下面是一份常用配置示例,覆盖最高频的几项定制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 把前缀键从 C-b 改为 C-a(更顺手,和 screen 一致)
unbind C-b
set -g prefix C-a
bind C-a send-prefix # 连按两次 C-a 把前缀键本身发给程序

# 开启鼠标支持:可点击切换窗格、拖拽调整大小、滚轮翻历史
set -g mouse on

# 窗口和窗格编号从 1 开始(默认从 0,但键盘 1 比 0 好按)
set -g base-index 1
setw -g pane-base-index 1

# 增大历史回滚行数(默认 2000)
set -g history-limit 10000

# 用更直观的键来分割窗格:| 竖分,- 横分
bind | split-window -h
bind - split-window -v

# 重载配置的快捷键:C-a r
bind r source-file ~/.tmux.conf \; display "配置已重载"

# 状态栏配色与内容
set -g status-bg colour235
set -g status-fg white
set -g status-right "#[fg=cyan]%Y-%m-%d %H:%M" # 右侧显示日期时间

几点说明:

  • 前缀键改 C-a:这是最常见的改动,C-aC-b 好按。改完后前文所有 C-b 都要换成 C-a
  • set -g 里的 -g 是 global(全局生效),针对所有会话;setwset-window-option 的简写,设置窗口级选项
  • 鼠标支持:开启后能用鼠标点选窗格、滚轮翻屏,对新手友好。但要注意开了鼠标后,选中文本复制的行为会变(需配合 Shift 拖选走终端原生复制)
  • 配色 colour235:tmux 用 0–255 的颜色编号,colour235 是深灰,可按喜好调

配置不必一步到位,从”改前缀键 + 开鼠标 + 调分割键”这三项开始,用熟了再逐步加。

小结

tmux 的核心就是两件事:一屏多用(分屏)和会话持久(断线不丢现场)。掌握它只需抓住三层模型和一套快捷键。

维度 关键点
三层模型 会话 session → 窗口 window → 窗格 pane,由外到内
持久化 C-b d 分离、tmux attach 接回,进程在后台不挂
前缀键 默认 C-b,所有快捷键先按它;常改为 C-a
分屏 C-b % 垂直、C-b " 水平、C-b z 全屏切换
配置 ~/.tmux.conf,优先改前缀键、开鼠标、调分割键