刚接手几台 Linux 服务器的时候,我踩过一个特别典型的坑:本地终端跑着长时间的数据处理任务,中午出去吃个饭,回来发现 SSH 连接断开了,几个小时的进度全部白费。后来跟一个前辈聊起这事,他反问我一句:“你不用 tmux 的吗?” 从那以后,tmux 就成了我连接服务器之后打开的第一个程序。今天这篇东西,就是想把这几年用 tmux 管会话窗口的实践经验完整梳理一遍,从基础概念到日常使用,再到多窗口协作和一些容易被忽略的操作细节,一次讲透。
1. 先搞清楚问题本质:为什么普通窗口一关任务就丢
在讲 tmux 之前,先聊聊它到底解决了一个什么痛点。很多人第一次接触 tmux 觉得很玄乎,不就是个终端吗?实际上它解决的是 Linux 服务器远端操作中一个非常致命的场景:进程的生命周期绑定在了连接会话上。
1.1 普通 SSH 会话的生命周期缺陷
你通过 SSH 登录一台远程服务器时,整个登录过程其实是一个前台进程组。所有在这个终端里启动的命令,都是这个会话的子进程。一旦网络波动、本地电脑休眠、或者你手滑关掉了终端窗口,SSH 连接就会断开,内核会向这个会话的所有进程发送 SIGHUP 信号。什么是 SIGHUP?字面意思就是“挂断”,这个信号默认的动作就是终止进程。
所以你会发现一个令人崩溃的现象:你在服务器上编译个内核,预计要跑四十分钟,结果跑了二十分钟网络闪断,重新连上去一看,终端里什么都没了,编译进程也死了。这不是服务器稳定性问题,而是 Linux 任务调度机制的一个天然属性:前台任务依赖终端连接的存在。
1.2 tmux 是怎么绕过这个限制的
tmux 的解决思路其实很巧妙,它引入了一个中间层。安装 tmux 之后,你不再是直接在你的终端里跑命令,而是在 tmux 里开一个虚拟会话。这个会话由 tmux 的服务端进程(server)维护,运行在服务器的后台,它不依赖任何 SSH 连接而独立存在。
理解一下这个模型:你通过 SSH 连上服务器,启动 tmux 客户端,然后跟 tmux server 之间建立一个“视线通道”。你在键盘上敲的命令,发给了 tmux server;tmux server 再转发给对应的 shell 进程。断网或者关闭 SSH 窗口,断掉的只是“视线通道”,tmux server 和它管理的所有子进程依然好好地跑在后台。等你重新连上服务器,再打开 tmux,就能重新接上刚才的会话,看到的所有内容都还在。
这个设计就好比你在一个房间里干活,tmux 是那个房间,你的 SSH 连接只是房间门口的一条门缝缝。门缝可以关上,但房间里的活儿照常干着。当初设计 tmux 的前身 screen 时,开发者就是瞄准了这个“会话保持”的需求。
1.3 为什么 nohup 在某些场景下不够用
说到这,肯定有人会问:那我用 nohup 把命令挂后台不也一样吗?确实,nohup command & 能在某些场景下让进程忽略挂断信号,继续在后台运行。但这个方案有几个非常难受的局限。
- nohup 跑起来的任务你看不到即时输出。虽然可以用
nohup.out文件重定向标准输出,但你想实时观察任务进度,就得另开窗口tail -f nohup.out,操作上很割裂。 - nohup 无法把前台任务重新拉回来。一旦你把任务丢到后台,后续想要交互式地输入指令,基本就别想了。
- nohup 对多任务管理非常薄弱。你同时挂了五六个后台任务,想要精确管理每一个,光靠 PID 记录和
kill命令去操作,效率极低。
简单说,nohup 适合“一次性、丢出去不管”的场景,但 tmux 适合的是“长时间运行且你需要随时进进出出维护”的场景。两者定位完全不同,但是后者在实际运维中占到了绝大多数比例。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. tmux 的三层结构和最常用操作流
用 tmux 之前,先建立一个整体的结构认知。tmux 的体系可以分成三层:会话(Session)→ 窗口(Window)→ 窗格(Pane)。
打个比方,Session 就像你开了一个独立的“工作间”,每个工作间里可以有多个 Window(相当于工作间里的多块白板),每块白板上又可以切分成多个 Pane(相当于把一块白板划成多个区域分别显示不同的内容)。日常运维中,90% 的场景其实只需要掌握 Session 和 Window 两层,Paner 属于锦上添花的高阶功能。
2.1 会话管理:create、detach、attach、kill
我个人的经验是,可以把 tmux 的会话管理当作“四板斧”来记忆:
| 操作 | 命令 | 说明 |
|---|---|---|
| 创建新会话 | tmux new -s work |
创建一个名字叫做 work 的会话 |
| 退出会话(分离) | Ctrl+b 然后按 d |
从当前会话中脱离,但会话继续在后台运行 |
| 查看所有会话 | tmux ls |
列出所有正在运行的会话 |
| 重连一个会话 | tmux attach -t work |
重新进入 name 为 work 的会话 |
| 重命名会话 | Ctrl+b 然后按 $ |
修改当前会话名称,方便管理多个任务 |
| 关闭整个会话 | tmux kill-session -t work |
直接终止会话及其中所有进程 |
这里要注意一个容易混淆的地方:关闭终端窗口不等于退出 tmux 会话。正确退出 tmux 会话的方式是先 Ctrl+b 再按 d(分离),或者等所有任务结束后输入 exit 退出 shell 来终止会话。如果你直接关闭终端,其实只是断开了连接,tmux 会话还挂在服务器上,下次登录还得记得重新 attach 回来。
实战里我见过不少新手把服务器上的 tmux 会话开了一大堆,既不命名也不清理,时间一长 tmux ls 一看几十个会话,完全分不清哪个是哪个。所以从第一天开始就养成好习惯:创建会话时永远带上 -s 参数指定一个有意义的名字,比如 tmux new -s nginx-deploy 或者 tmux new -s train-model。
2.2 前缀键逻辑:为什么总是 Ctrl+b
tmux 的命令不是直接按的,而是有统一的前缀键(Prefix Key)。默认前缀是 Ctrl+b,按下之后 tmux 进入“命令接收模式”,接下来你按的按键会被解释为 tmux 指令。
这个设计我觉得很聪明,相当于给 tmux 命令划定了一个独立“频道”,不会跟终端里正在运行的程序按键冲突。比如你在 Vim 里要移动光标,Vim 本身就用了很多 Ctrl 组合键,tmux 再加一个前缀键,两者就能和谐共存。
常用的一些前缀组合:
Ctrl+b c:创建一个新窗口Ctrl+b p/Ctrl+b n:切换到上一个 / 下一个窗口Ctrl+b 0~9:直接跳到编号对应的窗口Ctrl+b ,:重命名当前窗口(方便区分任务)Ctrl+b w:列出所有窗口,用方向键选择Ctrl+b f:在所有窗口中查找关键字并跳转Ctrl+b &:关闭当前窗口(tmux 会确认一次)
这些操作里,我用得最多的是 c、n、p、, 和 w。窗口重命名这个习惯尤其重要,Ctrl+b , 给窗口起个名字,比如“编译日志”“数据库操作”“nginx 调试”,多窗口切换时整个会话的条理感一下子就出来了。
2.3 首次配置:一份能长期使用的 .tmux.conf
tmux 默认配置其实很朴素,尤其是状态栏,系统负载、时间、窗口列表都没有,而且默认的激活键 Ctrl+b 按起来也不算顺手。我建议拿到新服务器后先写一份基础的 .tmux.conf 放到用户目录下,一次性配置好,之后每台机器都复制过去用。
给你看一份我个人长期在用的简化版配置:
bash复制# 设置前缀键为 Ctrl+a,比 Ctrl+b 按起来顺手
set -g prefix C-a
unbind C-b
bind C-a send-prefix
# 开启鼠标支持(方便滚动和选择窗格)
set -g mouse on
# 修改状态栏样式
set -g status-bg colour235
set -g status-fg colour250
set -g status-left "#[fg=green]Session: #S #[default]"
set -g status-right "#[fg=yellow]%H:%M #[default]"
# 窗口列表颜色
setw -g window-status-current-style bg=colour31
# 历史滚动的行数
set -g history-limit 10000
# 分屏后的窗格边框颜色
set -g pane-border-style fg=colour238
set -g pane-active-border-style fg=colour31
# 重新加载配置的快捷键
bind r source-file ~/.tmux.conf \; display "Config Reloaded!"
这份配置里我觉得性价比最高的几个改动是:鼠标模式、历史行数上限、以及前缀键。尤其是 history-limit,默认只有 2000 行,编译任务日志一刷就没了,调到 10000 之后回看日志会从容很多。改完配置后,在 tmux 里按 Ctrl+b 再按 r 就能热加载,不需要重启 tmux。
3. 多窗口与多窗格:把混乱的工作区整理出秩序
前面铺垫了这么多,接下来聊聊 tmux 真正让人效率起飞的部分:多窗口和多窗格的组合使用。
3.1 基于任务的窗口规划思路
以前我干活,习惯在服务器上开好几个 SSH 标签页,每个标签页负责一件事。用 tmux 之后,全部收敛到同一个 Session 里,用窗口来区分任务。一个窗口跑开发服务器日志,一个窗口连着数据库命令行,一个窗口用 Vim 改代码,最后再开一个窗口留作临时操作。这样整理下来,整个 Session 就是一个完整的项目工作台。
举一个实际部署场景的例子。比如我在部署一个 Web 服务,我会这样安排窗口:
- 窗口 0:Vim 编辑配置文件
- 窗口 1:日志输出窗口,专门
journalctl -f或者tail -f应用日志 - 窗口 2:执行部署脚本的窗口
- 窗口 3:数据库命令行窗口,用来解析 SQL 或排查慢查询
四个窗口在一个会话里,通过 Ctrl+b n / Ctrl+b p 反复横跳,不用来回切换 SSH 连接,也不用担心哪个终端窗口被误关。
3.2 水平垂直分屏:窗格的拆分、跳转与尺寸调整
如果说窗口解决了“多任务并行”,那窗格解决的就是“多任务在同一个视口内并行”。在 tmux 里分屏很直观:
Ctrl+b %:水平方向分屏,得到左右两个窗格Ctrl+b ":垂直方向分屏,得到上下两个窗格Ctrl+b 方向键:在窗格之间移动光标Ctrl+b x:关闭当前窗格Ctrl+b z:把当前窗格临时放大到全屏,再按一次还原
窗格组合最常用的一个场景是边跑测试边改代码。左边窗格跑着测试进程实时输出结果,右边窗格打开代码文件,改完保存直接看测试结果,省去切换窗口的认知成本。
窗格大小调整这块,如果你的 .tmux.conf 里没有自定义快捷键,默认的调整方式比较繁琐(Ctrl+b 后按 Ctrl+方向键)。我自己会在配置里加上两个更简单粗暴的绑定,直接用方向键配合 Alt 来调整:
bash复制bind -n M-Left resize-pane -L 5
bind -n M-Right resize-pane -R 5
bind -n M-Up resize-pane -U 5
bind -n M-Down resize-pane -D 5
这样在 tmux 里按住 Alt 加方向键,就能直接拖拽调整当前窗格大小。
3.3 窗格同步输入:批量操作多台机器的高效利器
多窗格还有一个隐藏很深但极度好用的功能:同步输入。你可以把当前会话里所有窗格当作一个大键盘,按下的键会同时发送到所有窗格。
操作方式是在命令行里输入:
bash复制:setw synchronize-panes on
关闭时把 on 改成 off 即可。
这个功能在批量操作多台同配置服务器时简直是神器。我有一次需要给三台应用服务器同时创建相同的目录结构并推送配置,以前要么写脚本循环执行,要么一台一台操作。用 tmux 之后,一个窗口横成三个窗格,分别 SSH 到三台机器,开启同步输入,敲一遍命令,三台机器同时执行。速度快且不容易漏。
不过这里必须提醒一句:同步输入是危险操作,一定要确保在多窗格连接的所有主机上执行的命令是无差别的。如果三台机器里有一台是数据库主库,另一台是应用服务器,那千万别开同步输入,更别不小心在某个窗格里敲了 rm 或 reboot。
3.4 会话、窗口还是窗格?一张图理清使用边界
聊到这里,把三者的使用边界理理清楚:
- 会话:对应一个大的工作任务或一个项目周期,比如“部署新版本”“迁移数据库”
- 窗口:对应一个具体的功能模块或一台远程主机的操作界面
- 窗格:对应同一功能模块内的并行子视图,比如同时看日志和改配置
如果是不同项目的任务,哪怕各自只有一两个窗口,我也会建议拆成独立的 Session 而不是硬塞到一个 Session 里。原因是 Session 可以独立命名、独立 attach/detach,互不影响。而 Window 和 Pane 在同一 Session 内是共享状态的,强制塞在一起容易出现操作混乱。
4. 从入门到实战:几个必须掌握的组合操作场景
到这里,基础命令已经覆盖得差不多了。接下来用几个实际场景演示一下这些操作是怎么组合起来的。这部分的经验我觉得比单纯记命令更有价值,毕竟命令是死的,场景是活的。
4.1 场景一:长任务跑到一半想回家,怎么办
最典型的就是模型训练或者大数据分析任务,本地终端挂着跑了两三个小时,但你不可能一直守在电脑前。
正确操作路径是:
bash复制# 1. 创建命名会话
tmux new -s train-task
# 2. 在会话里启动训练脚本
python train.py --epochs 200
# 3. 回到本地 Ctrl+b d 分离会话
# 4. 回家后重新登录服务器
tmux attach -t train-task
这里要强调一个关键认知:detach 和中断任务是完全不同的。detach 只是你不再“看着”任务运行,任务本身的运行状态一点都不会受到影响,进程照样跑,输出照样缓存。重新 attach 之后,你会发现窗口里保留着你离开前的所有输出,还会出现一个明显的分割线提示你“此处是重新连接时的位置”。
4.2 场景二:服务器日志实时追踪与排查
排查线上问题时,多窗口多窗格组合使用能极大压缩故障处理时间。我的习惯做法是:
- 窗口 0:登录应用服务器,运行
ls /var/log/nginx/ && tail -f /var/log/nginx/error.log - 窗口 1:连接数据库服务器,开启
SHOW FULL PROCESSLIST;循环查询 - 窗口 2:打开配置文件目录,准备随时修改并 reload
三个窗口三块信息面,排查效率比单开一个黑窗口高多了。
另外,tmux 的 history-limit 调大后,Ctrl+b [ 进入复制模式可以向上翻页浏览历史输出,排查问题的时候不用怕日志闪太快没看清。进入复制模式后,方向键滚动,按 Ctrl+空格 开始选择文本,按回车复制,Ctrl+b ] 粘贴,操作逻辑和 Vim 的 visual 模式很像。
4.3 场景三:服务器重启后 tmux 会话就没了,怎么办
很多人以为 tmux 是完美无缺的,但它也有一个明显短板:如果服务器本身重启了,tmux 会话和它底层的进程都会消失。tmux 保的是连接稳定,保不了系统断电。
针对这个问题,目前行业里比较主流的方案是配合 systemd 做服务化管理,而不是像很多教程说的用 tmux resurrect 插件。虽然 .tmux/resurrect 插件确实能保存并恢复窗口布局啊、环境变量啊这些信息,但它只能恢复到 tmux 层,本身不能把跑了一半的进程续上,意义不如 systemd 大。
如果你的工作场景允许把核心常驻任务改造成 systemd 服务,我建议优先考虑这个方案。比如说某个定时任务,你可以写成 systemd unit,配好 Restart=on-failure,系统启动后四十五秒自动拉起,这种强壮的恢复能力 tmux 靠自己是做不到的。但如果是临时性的长任务,比如跑一次数据清洗、一次性测试压测,那用 tmux 就够了,没必要为了这种任务去专门写 service 文件。长期服务和临时任务的边界要想清楚。
5. 比 tmux 本身更重要的:你的使用习惯与运维禁忌
最后这部分,想聊点 tmux 之外的“软技能”。工具再好用,如果使用习惯不好,照样会出各种问题。我总结了几个在实战中踩过坑后总结出来的使用禁忌。
5.1 明确会话命名与无人值守管理
永远不要嫌给会话起名字麻烦。一个拥有几十个 tmux 会话的服务器,如果每个会话都默认叫 0、1、2...排查问题时你只能一个个 attach 进去看,浪费时间不说还容易误操作成别的会话。建议每个会话名称都体现它的业务用途,比如 order-sync、backup-check、redis-migrate。配合 tmux ls 一眼就能看清当前服务器上所有正在运行的任务分布。
对于那些已经结束或不再需要的会话,及时清理掉。tmux kill-server 这个命令会把当前用户的所有 tmux 会话全部终止,如果服务器上还有其他同事在用同一个账号,千万不要随便执行这个命令,影响面太大。稳妥的做法是逐个 kill 掉自己不需要的会话:tmux kill-session -t <name>。
5.2 在 tmux 内使用更高效的编辑器与工作流
如果你还习惯在 tmux 里用 nano,我强烈建议空出两周时间把 Vim 的基础用法学一学。tmux 和 Vim 的组合是服务器端开发运维的传统黄金搭档。原因很简单:Vim 不需要鼠标,所有操作都在键盘上完成;而 tmux 本身也主要靠键盘控制,两者无缝结合,操作体验会非常顺滑。
推荐在 .tmux.conf 里加上这样一组配置,让 tmux 的窗格跳转和 Vim 的方向键保持一致:
bash复制# 把 Vim 的方向键跳转引入 tmux
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
这样在 tmux 里按 Ctrl+b h/j/k/l 就能实现窗格方向跳转,跟 Vim 的按键习惯完全统一,肌肉记忆只需一份。
5.3 一个很多人忽视的细节:清理滚动缓冲与输出
长时间运行任务会导致 tmux 的滚动缓冲区数据量膨胀,占用不少内存。尤其那些开了几十个窗口、历史输出十几万行的情况,会让 tmux 的内存占用异常夸张。Ctrl+b : 进入命令模式后执行 clear-history 可以清理当前窗格的滚动缓冲。另外周期性重启一下长期不用的 tmux 会话也有好处,相当于给会话瘦身。
但清理之前要注意,如果正在跑的任务还需要看历史输出,别手贱去清,清完找不回来了。
5.4 tmux 与 screen:简单做个选型说明
顺便解答一个超高频问题:tmux 和 screen 到底选哪个?
虽然 screen 出现得更早,在很多老系统上预装,但我会毫不犹豫推荐 tmux。原因有几个:一是 tmux 的配置语法更清晰,状态栏信息可定制性强很多,可以在状态栏显示当前目录、git 分支、负载信息等;二是 tmux 的窗格实现比 screen 的 split region 更成熟,操作更顺手;三是 tmux 有一个 plugin 生态,你可以按需安装,比如 tmux-resurrect 可以保存会话状态,tmux-yank 让复制粘贴更方便。
除非你维护的是一台历史悠久、连包管理器都不好用的老古董机器,否则直接上 tmux 就行,不要再纠结了。
6. 常见问题排查与“我不知道我竟然可以这样用”的瞬间
在各类照做 tmux 教程但总感觉哪里不对的反馈中,集中在这几个问题上。我整理一下逐个排掉,免得新人卡在第一步。
6.1 为什么 tmux 里显示 256 色不正常
经常有人遇到在 tmux 里打开 Vim,发现主题颜色跟裸终端完全不一样,颜色发灰或者奇奇怪怪。
这个问题的根源在于 tmux 默认声明的终端类型并不是 256 色支持的。解决办法是在 .tmux.conf 中加入:
bash复制set -g default-terminal "screen-256color"
set -ga terminal-overrides ",xterm-256color:RGB"
改完后重新加载配置,并且退出当前 tmux 会话再重进,颜色就恢复了。这里注意 set -ga 中的 a 表示追加(append),防止覆盖默认的 terminfo 配置。
6.2 tmux 里滚轮不好使
如果你没有开启鼠标模式,在 tmux 里滚动鼠标滚轮会直接作用到当前终端的内容而不是 tmux 缓冲区,很容易误触到 shell 的历史命令。解决方案已经写在前面了:.tmux.conf 中设置 set -g mouse on。开启后滚轮就能正常浏览 tmux 历史输出,还能方便地直接点击选中窗格。
6.3 tmux 中复制粘贴不跟系统剪贴板互通
默认情况下,tmux 复制的内容只能粘贴到 tmux 会话内。想实现与系统剪贴板互通,可以搜索安装 tmux-yank 插件,或者通过 ssh 配置把本地剪贴板打通。这里我提醒一个更简洁的做法:开启鼠标模式后,按住 Shift 键同时用鼠标选中文本,这个操作会直接走终端原生的选择逻辑,可以直接复制到系统剪贴板中。日常小批量复制用这个小技巧就够了,不用上插件。
6.4 用 tmux 跑交互式程序时界面渲染错乱
一些 TUI 交互式程序(比如 htop、nload、vim)在 tmux 里偶尔会出现渲染残影或者布局错乱,特别是重新连接会话之后。遇到这种情况我一般是按 Ctrl+b : 然后输入 refresh-client,或者干脆 Ctrl+b z 放大再还原一下窗格,大量情况下能刷新界面恢复正确渲染。如果还不行,Ctrl+b d 分离后重新 attach 基本也能解决。
6.5 tmux 会话插入错误内容(误在某个窗格输入了东西)
这个问题我必须单独拿出来强调一遍。在多窗格模式下,每个窗格都是独立的 shell,但它们的“键盘焦点”分布却完全取决于你的鼠标和跳转操作。尤其是开了鼠标模式后,点击事件只会改变焦点,不会让所有窗格取消接收输入的能力。如果不小心开启了 synchronize-panes 又没关,直接在一个窗格敲命令就会同步到所有窗格,在那个时刻如果各窗格处于不同目录、不同机器上,后果可能是灾难性的。
每次批量操作完之后,养成马上执行 :setw synchronize-panes off 的习惯。我自己也在配置里做了个高亮提示,让状态栏在同步模式开启时显示一个醒目的 SYNC 标识:
bash复制set -g status-right "#[fg=red]#{?window_synchronized,SYNC,}#[fg=yellow]%H:%M #[default]"
同步开启时右上角会显示红色 SYNC 字样,提醒自己当前处于群控模式。
6.6 如何在断网重连后快速恢复多个会话
如果服务器上挂了多个 tmux 会话,断网重连后一个一个 tmux attach -t 显然太慢了。可以写一个简单的脚本批量恢复你自己常用的会话:
bash复制#!/bin/bash
# tmux-restore.sh
for s in monitor deploy debug; do
tmux has-session -t $s 2>/dev/null || tmux new -d -s $s
done
tmux has-session -t $s 用来判断会话是否存在,不存在就用 -d 参数在后台静默创建。这样重连之后执行一次脚本,常用会话就全部就位,进入 tmux 后逐个切换即可。
6.7 tmux 里 ssh-agent 失效
这是一个非常隐蔽但影响很大的问题。你在本地 SSH 到跳板机,再从跳板机 SSH 到目标机器部署代码,需要走 SSH key 认证。目标机器上的 ssh-agent 是独立于 tmux 的,如果你在 tmux 里运行 ssh-add,会发现认证信息只保存在当前 shell 的 agent 环境变量里,重新 attach 一个会话后,环境变量变了,key 就找不到了。
解决办法是在 .tmux.conf 中加一个固定环境变量的设置:
bash复制set -g update-environment "SSH_AUTH_SOCK DISPLAY"
但我更推荐的做法是直接把 ssh-agent 的服务管理交给 systemd user 实例,或者使用 keychain 这类工具来管理 agent 生命周期,折腾一次后面就都顺了。
7. 把 tmux 变成你自己的运维驾驶舱
写了这么多,最后想聊点走心的。
工具这东西,光看命令清单是永远学不会的,真正让你变强的是场景化应用和肌肉记忆。我从第一次在 tmux 里救命式地保住了数据库迁移进度开始,到现在把它当成所有服务器任务的标准入口,中间经历了大量“哦原来还可以这样”的瞬间。tmux 不复杂,它的核心思想就一句话:让你的工作任务脱离终端连接的束缚,保持常开。一旦接受了这个设定,所有操作逻辑都顺理成章了。
最后再分享一个很有用的习惯。我每接手一台新服务器,第一件事就是跑一遍下面的命令:
bash复制tmux new -s bootstrap
然后所有初始化配置、软件安装、环境检查全部在这个 bootstrap 会话里完成。网络断了重连,tmux attach -t bootstrap 就回到刚才的操作现场,永远不会因为半路断线导致装软件装到一半不知道装哪了。
希望这篇文章能帮你把 tmux 这块拼图拼进自己的日常工作流。工具不在多,关键是把一个工具吃透用透。等你也习惯了 tmux 的会话常开模式,再回头看那些裸终端直接干活的日子,大概率是回不去了。
