本周清单:让终端活得久一点
缘起
每周例行维护线上环境时,总会撞上同一个老毛病。
半夜三点在家连上跳板机修问题,修到一半母猫突然跳上桌子把网线扯歪。路由器重连花了十几秒,SSH 连接随之断开。等网络恢复再连回去,前半个小时敲的命令、翻的日志、临时起的端口转发,全都消失在黑屏里。只能重新连上、重新进目录、重新追日志,从头再来。
这不是个别情况。地铁信号断断续续、笔记本合盖休眠、公司 VPN 间歇性掉线......只要网络有一瞬间不稳定,纯 SSH 就会把整个终端现场一并带走。
本周的目标很朴素:让终端活得久一点。 换句话说,想让一个远程开发现场能在断线、锁屏、切网络之后,原原本本地等着我回来。
断线也要有现场
要实现这个需求,核心思路只有一个:把终端进程从 SSH 连接里剥离出来。
SSH 连接一断,Shell 就会收到 SIGHUP(挂起信号),它的子进程也会随之终止。要想躲开这个宿命,有两种思路:
- 后台化:用
nohup、disown把单个进程扔到后台,让它脱离当前 Shell。然而它们脱离的是 Shell,却没法脱离终端的会话模型。你仍然没法再用交互式界面回到那个top、less或者半输入的命令行里。 - 会话化:用终端复用器(terminal multiplexer)在远程主机上创建一个持久的会话。真正的 Shell、命令、编辑器全都跑在这个会话里。SSH 只是用来"查看"这个会话的窗口。断线了,会话还在后台默默运行;再连上,只需重新附着(attach)就能回到断线前的每一个窗格、每一个滚动历史。
市面上常用的复用器是 tmux 和 screen。这周我选定 tmux,理由是配置相对现代、窗格操作也更符合现在的用法习惯。
tmux 的心智模型
要用顺手,先得搞懂 tmux 的三层结构:
| 层级 | 名称 | 作用 |
|---|---|---|
| 第一层 | 会话(Session) | 最顶层的工作区。可以理解成"一项大任务"。例如 api-debug、infra-migrate、log-trace 各开一个会话,互不干扰。 |
| 第二层 | 窗口(Window) | 会话里的标签页。通常对应一个场景:一个窗口跑日志 tail、一个窗口开编辑器、一个窗口跑测试。 |
| 第三层 | 窗格(Pane) | 窗口里的分屏。最常用的场景:左边看 tail -f,右边敲修复命令,同一个窗口内同时操作。 |
所有操作都要经过一个前缀键(prefix)。默认是 Ctrl+b。按下前缀键再按功能键才会触发 tmux 的命令,而不是直接发给 Shell。
这个模型一旦刻进肌肉记忆,后续的分屏、切换都会快很多。
五分钟跑起来
下面以最常用的流程为例,假设已在远程主机上安装好 tmux(大多数主流发行版都能一行装上)。
1. 新建会话
1tmux new -s dev-s dev 给会话起个名字。起名的好处特别大:等断线重连时,不用去记一串数字编号,直接 tmux attach -t dev 就能回去。
2. 分屏工作
进到会话后,前缀键 Ctrl+b 配合下面的按键就能分屏:
| 按键(前缀后) | 效果 |
|---|---|
% | 左右垂直分屏 |
" | 上下水平分屏 |
o | 在窗格间循环切换 |
x | 关闭当前窗格(会提示确认) |
z | 临时最大化/还原当前窗格(排查日志时特别有用) |
举个最符合线上排查的组合:先 Ctrl+b " 把窗口一分为二,下半屏用来 tail -f app.log,上半屏用来跑 curl、查进程、改配置。两边共用同一个 Shell 历史上下文,信息对照起来省去来回切窗口的精力。
3. 断线重连
此时随便模拟断线:直接关闭终端窗口或者等网络闪断。远程主机上的 tmux 服务依旧健在,所有进程都还在跑。
重新连上 SSH 后,列出现存会话:
1tmux ls会看到类似输出:
1dev: 1 windows (created Sun Nov 01 02:14:23 2026) [120x40]直接附着即可:
1tmux attach -t dev屏幕会立马切回到断线前的分屏布局、光标位置、甚至还在滚动的日志内容。跟没断线几乎一模一样。
4. 收尾
临时用完且确定不再需要时,可以在附着状态下用 Ctrl+b d 脱离会话(会话仍留存后台)。如果这次任务彻底结束,进入会话后用 exit 逐个关闭窗格,最后关闭会话本身。
几个能省命的细节
用上 tmux 后,不用等到半夜断线才体会它的价值。日常里下面这些细节最能提升流畅度。
用窗口组织场景
一个会话别全塞进窗格。更顺的做法是用窗口划分职责:
| 按键(前缀后) | 效果 |
|---|---|
c | 新建窗口 |
n / p | 切换到下一个/上一个窗口 |
0-9 | 直接跳转到对应编号的窗口 |
, | 重命名当前窗口(强烈推荐给窗口起名,如 logs、build、db) |
比如 dev 会话下开三个窗口:editor(跑 vim/nvim)、logs(tail 各类日志)、ops(临时命令、压测、抓包)。切换窗口比在一堆窗格里找目标快太多。
复制模式,直接翻历史
在线上查故障时经常要往上翻十几分钟的日志。直接用终端的滚轮在某些 SSH 客户端配合 tmux 时会有延迟。推荐用 tmux 自带的复制模式:
Ctrl+b [进入复制模式- 用方向键、
PgUp/PgDn翻页翻历史 - 按
Space开始选中文本,方向键扩选 - 按
Enter复制选中内容并退出复制模式 - 切到需要粘贴的窗格,用
Ctrl+b ]粘贴
不用再折腾鼠标选中再右键复制,纯键盘也能把报错栈整段拷贝出来。
同步窗格:一键操作多台视角
有时要同时在同一批机器上跑同一条检查命令(虽然一般用 pssh 更合适,但临时应急时也很常用)。在同一个窗口里开多个窗格后,用下面方式开启同步:
1Ctrl+b :setw synchronize-panes on此时往任意一个窗格里敲的每个字符都会同时发送到该窗口的所有窗格。跑完再关掉:
1Ctrl+b :setw synchronize-panes off只用在"完全相同的上下文、完全相同的命令"这种极为临时的场景。千万别用来编辑不同文件,不然改错一个就等于全改一遍。
让断线体验更顺滑
光装 tmux 还不够。配合 SSH 能减少绝大多数"莫名断线"带来的不适。
保持心跳
有些网络(尤其是公共 Wi-Fi、部分企业 VPN)会在空闲一段时间后静默掐断 TCP 连接。即使 tmux 在后台存活,SSH 也可能先一步断开。
在本地 ~/.ssh/config 里加上保活设置:
1Host *
2 ServerAliveInterval 60
3 ServerAliveCountMax 3
4 TCPKeepAlive yes含义:每 60 秒本地就会向远程发一个保活包。如果连续 3 次都没收到回应(也就是 180 秒无响应)才会认为连接失效并断开。比直接等运营商掐线要可预期得多。
用 mosh 当备选
如果经常在地铁这种极不稳定的网络下操作,可以试试 mosh。它基于 UDP 而不是 TCP,针对高延迟、丢包、切换基站这种场景做了针对性优化。即使 IP 换了(热点切换 4G/5G、从 Wi-Fi 切到流量)也能自动重连,输入也不会像 TCP 那样因为重传而一卡一卡的。
它和 tmux 并不冲突。最常见的组合是:用 mosh 连上主机,再 tmux attach 恢复会话。两者各管一块:mosh 管"网络连不连得上",tmux 管"现场丢不丢得掉"。
我的本周用法清单
折腾了几天后,我逐渐固定下了一套极简且够用的日常清单。没做复杂插件,只求稳定不踩坑。
| 场景 | 做法 | 备注 |
|---|---|---|
| 早晨开工 | ssh host && tmux attach -t dev | 如果会话不存在就 tmux new -s dev,养成一行走人的习惯。 |
| 长任务 | 在单独窗格里跑编译、迁移脚本 | 断线了也照跑,不用守着终端等它结束。 |
| 排查线上 | 新开 trace 会话,分两窗格看日志+敲命令 | 出事时直接切到这个会话,心态也能快点平复。 |
| 临时应急 | 用窗口而不是堆砌十个窗格 | 窗格太多反而眼花缭乱,窗口切换反倒更省脑力。 |
| 下班收工 | Ctrl+b d 脱离即可 | 不用刻意 kill,周末再连回来一切还在。 |
踩过的两个小坑
实践中也踩了点弯路,记下来省得下次再忘。
1. 颜色显示错乱
有时从某些终端模拟器连上后,grep --color、ls --color 的配色全是花花绿绿的乱码。根源是 TERM 环境变量对不上。进到 tmux 后尝试改成较常用的值:
1export TERM=tmux-256color如果远程主机的 terminfo 里确实没有 tmux-256color,退一步用 screen-256color 也大概率够用。最省事的做法是把这行加到远程的 ~/.bashrc 或 ~/.zshrc 里,进 Shell 时自动生效。
2. 合盖休眠导致的假死
笔记本合盖休眠再开盖,SSH 连接有时会"假死":敲键盘没反应,过十几秒才突然刷出一堆积压的输出。前面加的 ServerAliveInterval 能缓解大部分情况,但极少数客户端还是会卡住。此时不用强制关终端,直接开个新终端重连再 tmux attach 就好。旧连接最终会自己超时断开,并不会影响后台的 tmux 会话。
写在周末
回顾这周,收获最大的不是学会了多少快捷键,而是心态上的松动。
以前排查线上问题总有种"绷着"的感觉:生怕走神、怕断网、怕休息一会儿现场就没了。每次临时去倒杯水都要权衡一下要不要先把命令后台化。
现在只要建好会话,心里就多了一分笃定。断线了就断线,吃饭、通勤、睡觉该干啥干啥。等有空了再打开终端、连上主机、附着会话,所有东西都原封不动地等我回来接着干。
下周我不打算继续堆新功能,打算花十分钟把常用快捷键抄到便签上,直到它们不用再去翻帮助页为止。比起装一堆花里胡哨的插件,先把这套最朴素的"断线重连"用到烂,反而更可能真正在下次半夜掉线时派上用场。