跳过正文
  1. 工具/

tmux 完全指南:原理、使用教程与实战场景

20 分钟·
x
作者
x
熟练掌握Spring Boot、Spring Cloud等Java技术栈,专注于分布式系统设计与微服务架构。热爱技术分享,探索编程之美。
目录

如果你有过这样的经历——SSH 连着服务器跑一个几小时的编译/迁移任务,网断了,任务也死了;或者每天开发前要手动开五个终端标签页,一个跑服务、一个跑日志、一个连数据库、一个跑测试、一个敲 git——那 tmux 就是为你准备的。

tmux(terminal multiplexer,终端复用器)做的事一句话概括:把"终端窗口"和"跑在里面的进程"解耦。进程活在一个常驻后台的 tmux 服务器里,你的终端只是一个随时可以拔掉、换台机器再插上的显示器。

本文分三部分:先讲原理(理解了原理,后面所有行为都不需要死记)、再讲使用教程(从零到能用的最短路径 + 速查表)、最后讲tmux 到底能做什么(实战场景与脚本)。

本文所有命令、按键、默认值均以 tmux 3.7b 为准(较老的 2.x 版本部分选项名和默认值不同,文中会标注)。

一、原理:tmux 到底是怎么工作的
#

1.1 客户端 / 服务器架构
#

这是理解 tmux 的第一把钥匙:你输入的 tmux 命令不是"那个跑着你程序的东西",它只是个客户端。

   你的终端 (Alacritty / iTerm / Windows Terminal / ssh)
        │  键盘输入 / 屏幕输出
   ┌─────────────┐        Unix domain socket
   │ tmux client │◄──────────────────────────────┐
   └─────────────┘   /tmp/tmux-1000/default      │
                                    ┌────────────────────────────┐
                                    │      tmux server           │
                                    │  (常驻后台的单个进程)      │
                                    │                            │
                                    │  session: work             │
                                    │    ├── window 0: editor    │
                                    │    │     ├── pane %0 ──► nvim
                                    │    │     └── pane %1 ──► go run
                                    │    └── window 1: logs      │
                                    │          └── pane %2 ──► tail -f
                                    │  session: ops              │
                                    │    └── window 0 ──► bash   │
                                    └────────────────────────────┘

几个关键事实:

事实含义
server 是单个进程,管理所有 sessiontmux kill-server 会一次干掉所有会话,慎用
client 与 server 通过 Unix socket 通信默认路径 /tmp/tmux-$UID/default,可用 -L name 换 socket 名、-S path 换路径
第一次执行 tmux 时 server 才被拉起之后所有 tmux xxx 命令都只是"给 server 发一条指令"
client 不持有任何业务进程所以 client 死掉(网断、终端关闭)对 pane 里的进程毫无影响
server 内部是 libevent 事件循环单线程处理所有 pty 读写、client 通信、定时器(如状态栏刷新)

你可以亲眼验证这个架构:

# 看进程树:server 和 client 是两个独立进程
pgrep -a tmux
# 3721 tmux: server
# 8899 tmux attach

# socket 就是一个文件
ls -l /tmp/tmux-$(id -u)/
# srwxrwx--- 1 zhxu zhxu 0 Jul 30 08:39 default

# 用不同 socket 起一套完全独立的 tmux(互不可见)
tmux -L test new -s foo

1.2 伪终端(pty):断线不死的真正原因
#

第二把钥匙是 pty(pseudo terminal,伪终端)

Linux 上的终端设备是一对 master/slave:写进 master 的数据从 slave 读出来,反之亦然。tmux server 为每个 pane 创建一对 pty,自己拿着 master 端,然后 fork 出 shell,把 shell 的 stdin/stdout/stderr 都接到 slave 端,并把 slave 设为该进程的控制终端

        ┌───────────────── tmux server ─────────────────┐
        │                                               │
 client │   pty master  ◄────► [ 终端仿真 + grid 缓冲 ]  │
 ◄──────┼───────────────┐                               │
        │               │                               │
        └───────────────┼───────────────────────────────┘
                  pty slave (/dev/pts/7)
                        │ 作为控制终端
                  bash ──► go run ./main.go

于是就有了下面这条因果链,它解释了 tmux 最核心的价值:

你的程序的控制终端,是 tmux server 持有的 pty,而不是 ssh 分配的那个 pty。 ssh 断开时,内核只会向 ssh 那个 pty 的前台进程组SIGHUP——而你的程序根本不在那里。 tmux server 是 ssh 的子进程吗?不是,它在第一次启动时就 daemon 化脱离了。 所以:网断了,server 活着,pane 里的进程连一个信号都收不到,它甚至不知道发生了什么。

这也顺带解释了另外几个现象:

  • 为什么 tmux 里能正常用 vim、htop、Ctrl-C、作业控制? 因为 pane 里是一个真正的 pty,有控制终端、有前台进程组、支持 termios(行编辑、信号字符)。这是 tmux 和 nohup/& 的根本区别——后者只是重定向了 stdout,程序拿不到交互终端。
  • 为什么 tail -f 在 pane 里知道自己"不是管道"? isatty() 返回真。很多程序(git、ls、docker)会因此保留彩色输出,这也是 tmux capture-pane 抓到的内容带颜色的原因。
  • 为什么改变窗口大小,vim 会自动重排? tmux server 检测到 client 尺寸变化,ioctl(TIOCSWINSZ) 改 pty 尺寸,内核向前台进程组发 SIGWINCH

1.3 屏幕状态:为什么重连后画面还在
#

nohup ./task & 也能让任务在断线后活着,但你再也看不到它之前打印了什么。tmux 能,因为 server 内部为每个 pane 维护了一份屏幕状态(grid)

pane 的内存结构(简化)
├── 可见屏幕:80×24 的字符网格,每格存 字符 + 前景色 + 背景色 + 属性(粗体/下划线…)
├── scrollback 历史:向上滚动的行,上限由 history-limit 决定(默认仅 2000 行)
└── 终端状态机:光标位置、当前 SGR 属性、备用屏幕(alternate screen)、模式标志…

tmux server 本身就是一个终端仿真器:它解析程序输出的 ANSI 转义序列(\e[31m 变红、\e[2J 清屏、\e[?1049h 切备用屏幕),把结果画进 grid。你 attach 的那一刻,server 只是把 grid 重新渲染成转义序列发给你的真实终端——所以画面"还在"。

由此推出两个非常实用的结论:

  1. history-limit 默认只有 2000 行,跑长任务时上翻找不到早期日志是必然的,配置里应该调大(见 4.1)。
  2. 因为 grid 在 server 内存里,可以随时程序化读取——这就是 tmux capture-pane -p 能把任意 pane 的当前内容打印到 stdout 的原理,自动化脚本里非常好用(见 5.4)。

1.4 三层对象模型:session / window / pane
#

session(会话)  ── 一个工作上下文,attach/detach 的单位,独立于任何终端
  └── window(窗口) ── 相当于"标签页",占满整个可见区域,同一时刻只显示一个
        └── pane(窗格) ── 窗口内的矩形分割,每个 pane 一个 pty + 一个进程
对象编号/标识常见误解
session名字(work)或序号不是"一个终端窗口",而是一组窗口的集合
windowsession:indexwork:1默认从 0 开始(base-index 0),常改成 1 更顺手
pane%0%1(全局唯一 ID)pane ID 不随移动改变,写脚本时用 %id 比用序号可靠

值得单独说的是 window 可以被多个 session 共享link-window),session 可以成组new-session -t existing:新 session 与原 session 共享同一批 window,但各自独立地"当前显示哪个 window")。这是"两个人看同一批窗口、但各看各的"的底层机制。

多个 client 同时 attach 同一个 session 时,尺寸冲突由 window-size 选项决定(默认 latest,以最近活跃的客户端为准;也可设 smallest/largest/manual)。

1.5 前缀键为什么必须存在
#

pane 里跑着 vim、emacs、htop,它们要吃掉几乎所有按键。tmux 必须能区分"这个键是给我的"还是"透传给程序",所以引入了前缀键(prefix):默认 Ctrl-b,按下后 tmux 进入"下一个键归我"的状态。

本质上 tmux 维护若干键表(key table)

key table何时生效
root平时(默认几乎为空,所以按键都透传给程序)
prefix按下前缀键之后的那一个键
copy-mode / copy-mode-vi进入复制模式后
tmux list-keys -T prefix     # 看前缀键表里所有绑定
tmux list-keys -T root       # 看直接生效的绑定(鼠标绑定都在这里)

理解这一点,你就知道为什么嵌套 tmux(本地 tmux 里 ssh 到远端再开 tmux)需要按两次前缀:外层 tmux 先吃掉 C-b,再按 C-b(绑定为 send-prefix)才会把一个真正的 C-b 字节透传给内层。

1.6 双层终端仿真与 TERM
#

tmux 的位置很特殊:它对上是终端应用(向你的真终端输出转义序列),对下是终端仿真器(为 pane 里的程序提供终端能力)

真终端 (支持真彩色、OSC 52、图片协议…)
   ▲ tmux 按 外层 TERM 的能力输出
 tmux server ── 内部维护 grid
   │ 向 pane 内程序宣告能力:TERM=tmux-256color
 nvim / htop / less

这就是 tmux 里颜色/按键/剪贴板"偶尔出问题"的根源——能力必须在两层都存在

  • 内层程序通过 TERM(tmux 3.x 默认给 tmux-256color;2.x 老版本默认是 screen,只有 8 色)查 terminfo 决定敢用什么。
  • tmux 自己是否把某些能力转发给外层真终端,取决于 terminal-features / terminal-overrides(真彩色 RGBCtrl-Shift 类扩展按键 extended-keys、剪贴板 set-clipboard 走 OSC 52 等)。

所以正确的姿势是:外层终端的 TERM 要如实(如 xterm-256color),tmux 内的 default-terminaltmux-256color,真彩色靠 terminal-features 补声明——而不是到处乱写 TERM=xterm-256color。具体配置见 4.1。

1.7 一切都是命令
#

最后一把钥匙:tmux 没有"按键功能"这种东西,只有命令。 按键只是命令的绑定,配置文件只是一串开机执行的命令,tmux 命令行也是把命令发给 server:

# 这三者执行的是同一个东西
# ① 按键:C-b %
# ② tmux 命令提示符(C-b :)里输入:split-window -h
# ③ shell 里:
tmux split-window -h

所以:凡是你能手动做的操作,都能被脚本调用。这是第五章所有自动化玩法的基础。

二、安装与最短上手路径
#

2.1 安装
#

# Debian / Ubuntu
sudo apt install tmux
# Arch
sudo pacman -S tmux
# macOS
brew install tmux
# CentOS / RHEL
sudo yum install tmux

tmux -V   # 确认版本,3.x 以上默认值更合理

2.2 五分钟能用起来
#

tmux                      # 开一个匿名会话(不推荐,名字是 0、1、2…)
tmux new -s work          # ✅ 开一个叫 work 的会话
# ……干活……
# 按 C-b d 脱离(detach),任务继续跑

tmux ls                   # 看有哪些会话
# work: 2 windows (created Thu Jul 30 09:00:20 2026)

tmux attach -t work       # 重新接回来(可简写 tmux a -t work)
tmux kill-session -t work # 确认不要了再关

最该先背下来的一条命令是这个,它解决了"到底该 new 还是 attach"的纠结:

tmux new -A -s work   # 存在就 attach,不存在就创建(-A = attach if exists)

放进 ~/.zshrc / ~/.bashrc 里当别名,日常只需要敲 w

alias w='tmux new -A -s work'

2.3 最该先记住的六个按键
#

新手不要一次背全表,先记这六个,别的现查:

按键作用
C-b ddetach,把会话丢到后台(最重要
C-b c新建 window
C-b n / C-b p / C-b 数字切 window
C-b % / C-b "左右分屏 / 上下分屏
C-b 方向键在 pane 之间跳
C-b z当前 pane 全屏放大 / 还原(zoom,救命键)

记不住时:C-b ? 列出所有绑定(q 退出),C-b / 后按某个键可以查那个键干什么。

三、按键与命令速查表
#

以下均为 tmux 3.7b 默认绑定(前缀 C-b)。左列是按键,右列括号里是等价命令,方便写脚本时对照。

3.1 会话(session)
#

按键作用(等价命令)
C-b ddetach(detach-client
C-b $重命名当前会话(rename-session
C-b s交互式选择会话/窗口树(choose-tree -Zs
C-b ( / C-b )切到上一个 / 下一个会话(switch-client -p/-n
C-b L切回上一次的会话(switch-client -l
C-b D选择一个客户端把它踢下线(choose-client
C-b C-z挂起客户端(suspend-client,回 shell 后 fg 回来)

命令行侧:

tmux ls                            # list-sessions
tmux new -s name -d                # 后台创建,不 attach
tmux new -A -s name                # 有则 attach,无则创建
tmux attach -t name                # attach
tmux attach -d -t name             # attach 并把其他客户端踢掉(-d = detach others)
tmux attach -r -t name             # 只读 attach(read-only,演示/围观用)
tmux rename-session -t old new
tmux kill-session -t name
tmux has-session -t name 2>/dev/null && echo exists   # 脚本里做判断

3.2 窗口(window)
#

按键作用(等价命令)
C-b c新建窗口(new-window
C-b ,重命名窗口(rename-window
C-b &关闭窗口(kill-window,会二次确认)
C-b n / C-b p下一个 / 上一个窗口
C-b 0C-b 9按序号跳转
C-b l切回上一个窗口(last-window)
C-b w交互式窗口列表(choose-tree -Zw
C-b f按内容搜索窗口(find-window,忘了在哪个窗口时神器)
C-b .修改当前窗口序号(move-window
C-b '输入序号跳转

3.3 窗格(pane)
#

按键作用(等价命令)
C-b %左右分屏(split-window -h
C-b "上下分屏(split-window -v
C-b 方向键切换 pane(select-pane -L/-R/-U/-D
C-b o / C-b ;顺序切下一个 / 切回上一个 pane
C-b q显示 pane 编号(紧接着按数字直接跳)
C-b zzoom:当前 pane 临时全屏(resize-pane -Z
C-b x关闭 pane(kill-pane,会二次确认)
C-b Space循环切换预设布局(next-layout
C-b M-1M-7直接套用布局:均分横排 / 均分竖排 / 主区上下 / 主区左右 / 平铺 …
C-b { / C-b }与上一个 / 下一个 pane 互换位置(swap-pane
C-b C-o整体轮转所有 pane(rotate-window
C-b C-方向键调整 pane 大小(1 格,可长按连发)
C-b M-方向键调整 pane 大小(5 格)
C-b !把当前 pane 拆成独立窗口(break-pane
C-b *新建浮动窗格new-pane,较新版本特性)
C-b t满屏时钟(clock-mode,纯好玩)

跨窗口/会话搬 pane(很多人不知道 tmux 能这么干):

# 把 3 号窗口的 pane 拉到当前窗口,左右并排
tmux join-pane -h -s 3
# 把当前 pane 送到 logs 窗口
tmux join-pane -t logs
# 把 pane 独立成窗口
tmux break-pane

或者交互式:先在源 pane 按 C-b m 打标记(mark),再到目标窗口执行 join-pane

3.4 复制模式与剪贴板
#

C-b [ 进入复制模式(也可以上翻页 C-b PageUp 直接进)。默认是 emacs 键位mode-keys emacs),习惯 vi 的记得在配置里改成 vi

vi 键位下(推荐配置见 4.1):

按键作用
C-b [进入复制模式
h j k l / w b / g G移动(同 vim)
C-u / C-d上/下翻半页
/ / ? 然后 n N向下/向上搜索、跳下一个/上一个匹配
Space开始选择
v开始选择(vi 风格,需配置绑定)
C-v切换矩形(块)选择
y / Enter复制并退出
q / Esc退出复制模式
C-b ]粘贴最近的缓冲区(paste-buffer
C-b =从粘贴板列表里选一个粘(choose-buffer
C-b #列出所有粘贴板(list-buffers

注意 tmux 的 buffer 和系统剪贴板是两回事。 打通两者有两条路:

# 路线 A:OSC 52(推荐,跨 SSH 也能用,前提是外层终端支持)
set -s set-clipboard on

# 路线 B:管到本机剪贴板程序(copy-pipe)
# Linux/X11:
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'xclip -selection clipboard -i'
# Wayland:
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'wl-copy'
# macOS:
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'pbcopy'

命令行侧同样可用,脚本里很方便:

tmux show-buffer                      # 打印当前 buffer
tmux save-buffer out.txt              # 存文件
tmux load-buffer <(pbpaste)           # 从外部灌进 tmux buffer
tmux set-buffer "hello"               # 直接塞内容

3.5 其他常用
#

按键作用
C-b :命令提示符,可执行任意 tmux 命令(万能出口
C-b ?列出所有键绑定
C-b i显示当前窗口信息(display-message
C-b ~查看 server 消息日志(排查配置报错)
C-b C交互式选项编辑器(customize-mode,忘了选项名时很好用)
C-b r刷新客户端(画面花了时按,refresh-client
C-b > / C-b <弹出 pane / window 操作菜单(鼠标党友好)

四、配置:一份可以直接用的 tmux.conf
#

4.1 推荐配置(带解释)
#

tmux 启动时按顺序加载 /etc/tmux.conf,然后是 ~/.tmux.conf $XDG_CONFIG_HOME/tmux/tmux.conf(3.1+ 支持后者,喜欢干净 home 目录的用它)。

# ============ 基础手感 ============
# 前缀键改成 C-a(更好按;代价是和 shell 的行首快捷键冲突,
# 所以再绑一个 C-a C-a 把真正的 C-a 送进去)
set -g prefix C-a
unbind C-b
bind C-a send-prefix

# 窗口/窗格从 1 开始编号,关掉窗口后自动重排序号
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on

# scrollback 默认只有 2000 行,太小
set -g history-limit 50000

# 开鼠标:滚轮翻历史、点击切 pane、拖边框调大小
set -g mouse on

# vi 风格的复制模式(默认是 emacs)
setw -g mode-keys vi
bind -T copy-mode-vi v send-keys -X begin-selection
bind -T copy-mode-vi y send-keys -X copy-pipe-and-cancel 'wl-copy'   # 按系统替换
set -s set-clipboard on          # 走 OSC 52,跨 SSH 也能复制到本机

# ESC 键延迟:3.x 默认已是 10ms,老版本是 500ms(会让 vim 的 ESC 发木)
set -s escape-time 10

# 让 vim 的 FocusGained/autoread 生效
set -g focus-events on

# ============ 颜色与终端能力 ============
set -g default-terminal "tmux-256color"
# 向外层真终端声明真彩色能力(把 xterm-256color 换成你外层实际的 TERM)
set -as terminal-features ",xterm-256color:RGB"

# ============ 更顺手的绑定 ============
# 分屏用 | 和 -(形状即所见),并继承当前目录
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
unbind '"'
unbind %
# 新窗口也继承当前目录
bind c new-window -c "#{pane_current_path}"

# 无前缀切 pane(Alt+方向键)
bind -n M-Left  select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up    select-pane -U
bind -n M-Down  select-pane -D

# 一键重载配置
bind R source-file ~/.tmux.conf \; display-message "tmux.conf reloaded"

# 同步输入到所有 pane(批量操作多台机器时开/关)
bind S setw synchronize-panes \; display-message "sync #{?pane_synchronized,ON,OFF}"

# 弹出层里开一个临时 shell(scratch),再按一次关掉
bind g display-popup -E -w 80% -h 80% -d "#{pane_current_path}"

# ============ 状态栏 ============
set -g status-position top
set -g status-interval 5
set -g status-left  " #[bold]#S #[default]"
set -g status-right " #{?pane_synchronized,#[reverse] SYNC #[default] ,}%Y-%m-%d %H:%M "
setw -g automatic-rename on

改完不用重启 server:C-b : 输入 source-file ~/.tmux.conf,或者用上面绑的 C-b R

⚠️ 配置里写错选项名不会有弹窗,只会静默失败——C-b ~(show-messages)能看到报错。

4.2 关于插件(TPM)
#

tmux-plugins/tpm 是社区标准插件管理器。真正值得装的其实就两三个:

插件解决什么
tmux-resurrect把会话布局/窗口/工作目录存盘,服务器重启后能恢复(tmux server 一死,session 就没了,这是 tmux 唯一"不持久"的地方)
tmux-continuum给 resurrect 加自动定时保存
vim-tmux-navigator用同一套 C-h/j/k/l 在 vim 分屏和 tmux pane 之间无缝跳

其余美化类插件按需,不装也完全够用。如果你不想引入插件,tmux-resurrect 的替代方案是自己写一个"布局启动脚本"(见 5.3)——很多人最后都走到了这条路上,因为可复现的布局脚本比恢复快照更可靠

五、tmux 能做什么:实战场景
#

5.1 长任务不怕断线(最基础也最值钱)
#

ssh server
tmux new -A -s migrate
./long_migration.sh        # 跑起来
# C-b d 脱离,直接关笔记本回家

# 第二天,换台机器
ssh server
tmux a -t migrate          # 画面、滚动历史、进度条全都在

nohup 强的地方:有交互终端(可以中途 Ctrl-C、可以回答 y/n 提示、可以在旁边新开 pane 看日志),且能看到历史输出

5.2 一屏搞定开发环境
#

典型布局:左边编辑器占大半,右上跑服务,右下跑测试/日志。

┌──────────────────────┬──────────────┐
│                      │  go run .    │
│        nvim          ├──────────────┤
│                      │  tail -f log │
└──────────────────────┴──────────────┘

手动搭:C-b % 分左右 → 右边 C-b " 分上下 → C-b M-方向键 调宽度。搭好后 C-b z 可以随时把任意 pane 临时放大看细节。

5.3 用脚本一键拉起整套工作区
#

因为"一切都是命令",工作区可以完全脚本化。把下面存成 ~/bin/dev

#!/usr/bin/env bash
set -euo pipefail

SESSION="dev"
ROOT="$HOME/GolandProjects/lee"

# 已存在就直接接进去,不重复创建
if tmux has-session -t "$SESSION" 2>/dev/null; then
  exec tmux attach -t "$SESSION"
fi

# 后台创建会话和第一个窗口
tmux new-session -d -s "$SESSION" -c "$ROOT" -n editor
tmux send-keys   -t "$SESSION:editor" 'nvim .' C-m

# 第二个窗口:上下两个 pane,一个跑服务一个跑日志
tmux new-window  -t "$SESSION" -c "$ROOT" -n server
tmux send-keys   -t "$SESSION:server" 'hugo server -D' C-m
tmux split-window -t "$SESSION:server" -v -c "$ROOT"
tmux send-keys   -t "$SESSION:server.2" 'git status' C-m

# 第三个窗口:留个干净 shell
tmux new-window  -t "$SESSION" -c "$ROOT" -n shell

tmux select-window -t "$SESSION:editor"
exec tmux attach -t "$SESSION"

一行流版本(临时用,不值得存文件时):

tmux new -d -s tmp 'top' \; split-window -d 'htop' \; attach

想要声明式配置的话,tmuxinator(Ruby)/tmuxp(Python)用 YAML 描述布局,本质上就是帮你生成上面这堆命令。项目不多的话,一个 shell 脚本反而更好维护。

5.4 把 tmux 当成"自动化机器人的手"
#

这是很多人忽略的用法:tmux 让脚本能操作一个交互式终端会话——包括那些没有 API、只能人肉敲的程序。

# 向某个 pane 敲键盘(C-m = 回车)
tmux send-keys -t dev:server.1 'make build' C-m

# 抓取 pane 当前屏幕内容(-p 打到 stdout,-S -100 含最近 100 行历史)
tmux capture-pane -p -t dev:server.1 -S -100 | tail -20

# 轮询等某个关键字出现(简易"等服务起好")
until tmux capture-pane -p -t dev:server.1 | grep -q 'Listening on'; do sleep 1; done

# 把某个 pane 的输出实时落盘(开关式)
tmux pipe-pane -t dev:server.1 -o 'cat >> /tmp/server.log'

# 读取结构化信息,写监控脚本很好用
tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_current_command} #{pane_pid}'

值得一提的现实场景:跑长时间的 AI 编码 agent / CLI 工具。这类进程既要交互(要能看输出、随时插话),又动辄跑几十分钟,还怕网断——正好是 tmux 的靶心。给每个项目开一个命名会话(cc-blogcc-homelab),断线后 tmux a -t cc-blog 接回去,全程不丢上下文;配合 capture-pane 还能在外部脚本里检查它进展到哪了。

5.5 同时操作多台机器
#

# 四个 pane 分别 ssh 到四台机器
tmux new -s fleet \; \
  send-keys 'ssh web1' C-m \; \
  split-window -h 'ssh web2' \; \
  split-window -v 'ssh web3' \; \
  select-pane -t 1 \; split-window -v 'ssh web4' \; \
  select-layout tiled

# 打开输入同步:敲一次,所有 pane 一起执行
# C-b : setw synchronize-panes on     (或用 4.1 里绑的 C-b S)

同步输入是把双刃剑,rm -rf 也会同步。养成用完立刻关掉的习惯,状态栏上加个 SYNC 提示(见 4.1 配置)。

5.6 结对编程 / 教学演示 / 远程支援
#

同一台机器上的两个用户 attach 同一个 session,就能看到同一个屏幕。

# 方式一:同一用户、多个终端 attach 同一会话(最简单)
tmux a -t work           # 两边都看到同样画面,鼠标/键盘都能操作
tmux a -r -t work        # 围观者用只读模式,防手滑

# 方式二:两人各看各的窗口,但共享同一批窗口(会话组)
tmux new-session -t work -s work-guest

# 方式三:不同用户共享(需要放开 socket 权限,注意安全边界)
tmux -S /tmp/pair new -s pair
chmod 1777 /tmp/pair     # 另一用户: tmux -S /tmp/pair attach
tmux server-access -w otheruser   # 3.3+ 显式授权写权限

跨公网协作现在更常用 tmate(tmux 的 fork,自带中转服务器,一条链接分享);如果双方本来就能 ssh 到同一台机器,原生 tmux 就够了。

5.7 日志/监控墙
#

tmux new -s watch -d 'journalctl -f -u caddy'
tmux split-window -t watch -v 'journalctl -f -u artalk'
tmux split-window -t watch -h 'htop'
tmux select-layout -t watch tiled
tmux a -t watch

配合 C-b z 放大某一格看细节,比开四个终端标签页来回切要顺手得多。

5.8 弹出层当"随手终端"
#

# 临时窗口,退出即销毁(-E),不打乱现有布局
tmux display-popup -E -w 80% -h 80% -d "#{pane_current_path}"

# 弹出层里跑单个命令
tmux display-popup -E -w 70% -h 70% 'lazygit'

绑到一个键上(4.1 里的 C-b g),就得到一个"随时呼出、随时收起"的临时 shell —— 查个文档、跑个 git、看眼 k9s,不用为此新建 window。

5.9 tmux 不该做什么
#

诚实地说清楚边界,能省掉很多坑:

  • 不要用 tmux 当服务守护进程tmux new -d 'my-server' 能跑,但没有自动重启、没有日志轮转、开机不自启、kill-server 就全没。生产上用 systemd(systemd-run/user service),tmux 留给"人要看的东西"。
  • 不要指望 tmux 持久化到重启之后。server 进程一死,所有 session 都消失(tmux-resurrect 或布局脚本才是答案)。
  • 不要用它替代终端本身的能力。图片显示、字体、GPU 渲染归终端管;tmux 的双层仿真反而可能挡住这些特性(如部分图片协议、部分扩展按键)。

六、常见坑与排查
#

现象原因解法
tmux 里颜色变少 / vim 主题发灰TERM 只宣告了 8/16 色(老版本默认 screenset -g default-terminal "tmux-256color",真彩色再加 set -as terminal-features ",xterm-256color:RGB"
外面能显示的颜色,进 tmux 就丢外层终端 TERM 被写错,或没声明 RGB 能力检查 tmux 外 echo $TERM,别到处硬写 xterm-256color
vim 里按 ESC 反应发木老版本 escape-time 默认 500msset -s escape-time 10(3.x 已默认 10)
上翻找不到几分钟前的日志history-limit 默认仅 2000 行set -g history-limit 50000
鼠标选中复制不到系统剪贴板tmux buffer ≠ 系统剪贴板set -s set-clipboard on,或用 copy-pipewl-copy/pbcopy/xclip
开了 mouse 后没法用鼠标选文字了鼠标事件被 tmux 接管按住 Shift 拖拽走终端原生选择;或复制模式里选
嵌套 tmux 时前缀键失效外层先吃掉了前缀内层操作按两次前缀(send-prefix),或给内外层设不同前缀
Ctrl-方向键Ctrl-Shift-x 在 tmux 里不生效扩展按键默认不转发set -s extended-keys on(并确认外层终端支持)
vim 的 autoread / 焦点事件失灵focus-events 默认 offset -g focus-events on
修改了配置没反应配置只在 server 启动时执行;或选项名写错静默失败source-file 重载;C-b ~ 看错误消息
tmux ls 说 no server runningserver 已退出(所有 session 都关了/被 kill)正常现象,tmux new -s x 重开即可
误关了所有会话手滑 kill-server无法恢复,这就是要装 tmux-resurrect 或写布局脚本的理由

七、和其他方案的对比
#

方案定位相对 tmux
GNU screen老前辈,同样是终端复用器几乎所有系统预装;但分屏能力弱、配置和脚本能力差、社区活跃度低
zellijRust 写的现代复用器开箱即用、有界面提示、内置布局文件和插件(WASM);生态与远端普及度不如 tmux
dtach / abduco只做 detach/attach,不做复用极轻量,没有分屏/状态栏/复制模式;只想"断线不死"时够用
tmatetmux 的 fork专门解决跨公网共享终端,一条链接分享
终端自带标签页/分屏终端软件的功能本地体验好,但在远端不存在——ssh 一断全没,这是 tmux 不可替代的核心

一句话选型:要在服务器上活着、要脚本化、要普适(哪台机器上都有)→ tmux

八、最小速查卡
#

会话   tmux new -A -s name   开/接会话       C-b d   脱离
       tmux ls               列会话          C-b s   选会话
       tmux a -t name        接会话          C-b $   改名

窗口   C-b c 新建   C-b , 改名   C-b n/p 切换   C-b 1..9 跳转
       C-b w 窗口树 C-b f 搜索   C-b & 关闭

窗格   C-b % 左右分  C-b " 上下分  C-b 方向键 切换  C-b z 放大
       C-b x 关闭    C-b Space 换布局   C-b C-方向键 调大小
       C-b ! 独立成窗口   C-b q 显示编号

复制   C-b [ 进入   / 搜索   Space/v 选   y 复制   C-b ] 粘贴

万能   C-b :  命令行     C-b ?  所有绑定    C-b ~  错误日志

结语
#

tmux 的学习曲线几乎全部集中在"前缀键 + 三层模型"这一小段上,翻过去之后,它就变成了一个几乎无感的基础设施:你的工作上下文不再绑在某个终端窗口、某条网络连接、某台笔记本上

真正建议投入时间的三件事,收益远大于背快捷键:

  1. 写一份自己的 tmux.conf(照抄第四章,按手感改);
  2. 给每个常做的项目写一个布局启动脚本(第 5.3 节);
  3. 记住 capture-pane / send-keys——它们能把 tmux 从"人用的工具"变成"脚本能用的工具"(第 5.4 节)。

相关文章

AI Agent的记忆与技能系统:从失忆到越用越懂你

大语言模型本质上是无状态的——每次调用,模型对"你是谁"“上次聊了什么"“你喜欢什么风格"一无所知,除非这些信息被显式塞进当前的上下文窗口。这和 RAG 要解决的问题不是一回事:RAG 补的是模型"没见过的知识”,而这里要聊的是模型"没记住的经历”——同一个用户、同一个项目,换一次会话就打回原形,昨天纠正过的错误今天还会再犯一遍。

MCP的AI上下文管理心得

在使用 MCP(Model Context Protocol,模型上下文协议)构建 AI 应用的过程中,上下文管理是绕不开的核心话题。无论是对话系统、代码助手还是知识库问答,上下文的质量直接决定了 AI 响应的准确性和连贯性。本文结合实际使用经验,聊一聊在 MCP 体系下做好 AI 上下文管理的一些心得。

RAG检索增强生成:原理、数据切片与向量化详解

11 分钟
大语言模型(LLM)虽然拥有海量的通用知识,但它的知识边界止于训练数据的截止日期,也无法访问企业内部文档、私有数据库这类"没见过"的信息。想让模型回答这些问题,通常有两条路:**微调(Fine-tuning)把新知识"炼"进参数里,或者RAG(Retrieval-Augmented Generation,检索增强生成)**在回答前先把相关资料"喂"给模型。本文重点讲后者——它的基本原理、数据切片(Chunking)与向量化(Embedding)的具体做法,以及一个经常被混淆的问题:向量化和大模型训练到底是不是一回事。

OpenClaw 使用指南:用 Skills 实现 AI 全自动操控电脑

11 分钟
在 AI 浪潮席卷全球的今天,我们不再满足于让 AI 仅仅回答问题——我们希望 AI 能够真正帮我们干活。OpenClaw 正是这样一个框架:它让大语言模型(LLM)拥有"手脚",通过可插拔的 Skills(技能) 系统,让 AI 代理能够执行文件操作、运行命令、自动化浏览器、管理进程……几乎所有你能用鼠标键盘做的事,OpenClaw 都能让 AI 替你完成。

常见排序算法

4 分钟
排序算法是计算机科学中最基础也是最重要的算法之一。本文介绍几种常见的排序算法,并给出 Java 实现。

AI的发展与现状:从传统机器学习到MCP与Skills的新纪元

10 分钟
人工智能(Artificial Intelligence, AI)作为21世纪最具革命性的技术之一,正在深刻地改变着我们的生活方式、工作模式和社会结构。从早期的专家系统到如今的大语言模型,AI技术经历了多个发展阶段,而近期MCP(Model Context Protocol)和Skills的出现,更是将AI应用推向了新的高度。

TLS非对称加密流程详解:从握手到对称加密通信

13 分钟
TLS(Transport Layer Security,传输层安全协议)是互联网上最广泛使用的安全协议之一,它为客户端和服务器之间的通信提供了加密、身份验证和数据完整性保护。本文将详细介绍TLS握手过程中客户端和服务端的具体操作,包括CA证书验证、密钥交换,直到最终生成AES对称加密密钥进行正常通信的完整流程。

使用Debian作为路由器:完整配置指南

在企业环境或高级家庭网络中,使用Linux系统(特别是Debian)作为路由器可以提供更强大的功能、更高的灵活性和更好的性能。本文将详细介绍如何将Debian配置为功能完整的路由器,包括DHCP服务、DNS服务、NAT配置、IPv6中继、网桥设置等核心功能。