一句话总结
tmux 是终端复用器(Terminal Multiplexer):它在服务器上托管一个不随断线而消失的会话,里面可以开多个窗口和分屏.
SSH 断了,电脑关了,任务照跑,重连后 tmux attach 一切如初--这正是 nohup(第 14 篇)做不到的"现场可恢复".
解决什么问题
设想一个真实场景:SSH 到服务器跑一个两小时的数据迁移,跑到一半网络抖了一下,SSH 断开--前台进程收到 SIGHUP,任务直接死掉,白跑一小时.第 14 篇的 nohup 能让进程活下来,但再也看不到它的输出,没法和它交互了.
tmux 把整个"终端现场"搬到一个常驻服务器的会话里.SSH 只是"连上去看"这个会话;断开时会话继续在服务器上跑,重连后重新"接上"它,输出,分屏,正在编辑的文件,全都原样还在.
普通 SSH 像用遥控器直接操作电视--遥控器没电(断线),电视也跟着关.
tmux 则是电视一直开着自己播,SSH 只是一个随时能插拔的显示器:拔掉(detach)电视照常播,插回(attach)接着看.
任务的"生命"绑在服务器的会话上,不绑在那条易断的连接上.
tmux vs nohup vs iTerm2 分屏
三者别混:nohup(第 14 篇)只保进程不死,但无输出无交互;iTerm2 分屏(第 19 篇)是本地 GUI 层,断线即失;tmux 兼得--会话持久 + 多窗口分屏 + 断线重连可交互.
远程长任务,需要回来继续看的,选 tmux.
三层模型:Session / Window / Pane
tmux 的结构是三层嵌套,理解这个模型,所有命令就都顺了:
|
| 层级 | 类比 | 说明 |
|---|---|---|
| Session 会话 | 一整个浏览器窗口 | 最外层容器,可断开/重连;通常一个项目开一个 |
| Window 窗口 | 浏览器的标签页 | 会话内可有多个,底部状态栏列出,数字切换 |
| Pane 分屏 | 标签页内的分栏 | 把一个窗口切成多块,同时看多个命令 |
前缀键:tmux 的"指挥棒"
tmux 的所有快捷键都要先按前缀键(Prefix),默认是 Ctrl-b,再按功能键.比如"新建窗口"是先按 Ctrl-b 松开,再按 c--本篇记作 <prefix> c.
前缀键就像游戏手柄的"功能切换键":单独按方向键是走路(普通输入直接传给 Shell),先按住功能键再按方向键才是放技能(tmux 命令).
这样设计是为了不和终端里程序自己的快捷键冲突--只有以前缀键开头的按键才被 tmux 截获.
很多人把 Prefix 改成 Ctrl-a
Ctrl-b 按起来别扭,且它在 Shell 里本是"光标左移".常见做法是在 ~/.tmux.conf 里改成 Ctrl-a(更顺手,源自老牌工具 screen 的习惯).本篇仍以默认 Ctrl-b 讲解,改键方法见后面配置一节.
会话操作:断开与重连(最核心)
这是 tmux 价值的核心所在,优先记牢:
|
| 操作 | 命令 / 按键 |
|---|---|
| 新建命名会话 | tmux new -s 名字 |
| 断开当前会话 | <prefix> d |
| 列出所有会话 | tmux ls |
| 重连会话 | tmux attach -t 名字(或 tmux a -t 名字) |
| 在会话间切换 | <prefix> s(列出选择) |
| 关闭会话 | tmux kill-session -t 名字 |
detach 不是退出,exit 才是
区分两个动作:<prefix> d 是 detach(断开)--会话和里面的进程继续在后台活着;在 pane 里敲 exit 或 <prefix> & 才是真正关闭那个 window/会话.想让任务持续就用 detach,千万别习惯性 exit.
窗口操作
窗口(Window)像标签页,在底部状态栏一字排开,适合按"任务类型"分:一个窗口跑服务,一个看日志,一个写代码.
| 按键 | 作用 |
|---|---|
<prefix> c |
create 新建窗口 |
<prefix> 数字 |
切到第 N 个窗口 |
<prefix> n / p |
next / previous 下一个/上一个窗口 |
<prefix> w |
列出所有窗口供选择 |
<prefix> , |
重命名当前窗口 |
<prefix> & |
关闭当前窗口(会确认) |
分屏操作
分屏(Pane)把一个窗口切成多块.注意 tmux 默认的分屏键不太直观,很多人会在配置里改掉(见下节):
| 按键 | 作用 |
|---|---|
<prefix> % |
左右切开(垂直分屏) |
<prefix> " |
上下切开(水平分屏) |
<prefix> 方向键 |
在分屏间移动焦点 |
<prefix> o |
顺序切换到下一个分屏 |
<prefix> z |
zoom 当前分屏临时全屏,再按还原(高频!) |
<prefix> x |
关闭当前分屏(会确认) |
<prefix> 空格 |
循环切换分屏布局 |
用 % 表示垂直," 表示水平,确实反直觉.两个缓解办法:
- 看符号形状联想--
%中间有斜杠像左右隔开,"像上下两点 - 干脆在配置里改成好记的键(下节给出把它们改成
|和-的写法)
<prefix> z 全屏放大则务必记牢,看某个分屏的长输出时极其常用.
复制模式:翻屏与选取
tmux 里鼠标滚轮默认不滚历史,要进复制模式(Copy Mode) 才能往上翻看之前的输出:
<prefix> [进入复制模式,然后用方向键 / PageUp / PageDown 翻屏,q退出- 进入后可像 vim 一样移动;空格开始选择,回车复制选中文本(默认 vi 风格按键)
- 搜索:复制模式里按
/向下,?向上搜索关键词--在长输出里找东西很方便
开启鼠标支持省心很多
在 ~/.tmux.conf 加一行 set -g mouse on,之后就能用鼠标滚轮直接翻历史,点击切换分屏,拖拽调整分屏大小.对新手来说这是最值得先打开的一个选项,大幅降低上手门槛.
配置文件:~/.tmux.conf
tmux 的行为通过 ~/.tmux.conf 定制(和 Shell 的 .zshrc 是一个思路).下面是一份能解决前面所有"不顺手"的常用起手配置:
|
|
tmux 与 iTerm2 集成模式
承接第 19 篇:在 iTerm2 里用 tmux -CC new -s work 启动(-CC 是 control mode),iTerm2 会把 tmux 的 window 和 pane 渲染成自己的原生标签页和分屏--享受 tmux 的会话持久性,操作却用 iTerm2 熟悉的 ⌘T/⌘D.两个工具的优点合一,是 macOS 上的理想组合.
快速回顾
- tmux = 不随断线消失的终端会话:比 nohup 多了"可重连,可交互,带分屏",远程长任务首选
- 三层模型:Session(会话) ⊃ Window(窗口,如标签页) ⊃ Pane(分屏);理解它命令就顺了
- 所有快捷键先按前缀键(默认
Ctrl-b,常改Ctrl-a),再按功能键 - 核心三连:
tmux new -s 名建会话 ·<prefix> d断开(任务继续跑) ·tmux attach -t 名重连;detach ≠ exit - 窗口:
<prefix> c新建 · 数字切换 ·,重命名;分屏:%左右 ·"上下 ·z全屏放大(高频) - 复制模式:
<prefix> [翻历史,/搜索;开set -g mouse on可直接用滚轮和鼠标 - ~/.tmux.conf 定制:改前缀键,开鼠标,把分屏键改成
|/-;<prefix> r重载配置 - iTerm2 集成:
tmux -CC模式让 tmux 的持久性 + iTerm2 的原生分屏操作合一
动手练习
- 会话持久性:用
tmux new -s test建会话,里面跑sleep 600,按<prefix> d断开,tmux ls确认它还在,再tmux attach -t test回去看 sleep 是否还在跑 - 断线恢复(关键体验):SSH 到一台远程机器开 tmux 跑个任务,故意断开 SSH 再重连
attach,验证任务没死 - 窗口管理:在一个会话里用
<prefix> c开三个窗口,分别<prefix> ,命名为 server/log/edit,用数字键来回切换 - 分屏操作:在一个窗口里用
<prefix> %和<prefix> "切出三个分屏,用方向键切焦点,再用<prefix> z把一个放大再还原 - 复制模式:进入复制模式
<prefix> [,用方向键往上翻历史输出,再按/搜索一个关键词,q退出 - 配置定制:创建
~/.tmux.conf,加入set -g mouse on和把前缀键改成Ctrl-a,用tmux source-file ~/.tmux.conf重载并验证鼠标滚轮能翻历史 - iTerm2 集成:如果用 iTerm2,试试
tmux -CC new -s demo,观察 tmux 的窗口/分屏如何变成 iTerm2 的原生标签和分屏