ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

tmux 终端复用器完全指南:安装、配置与实战技巧

tmux 终端复用器完全指南:安装、配置与实战技巧 1. 终端复用到底解决的是什么问题很多人第一次听到 tmux 这个词第一反应是我平时就用个终端敲敲命令要这玩意儿干嘛。我当初也是这个想法直到有一次在远程服务器上跑一个数据清洗脚本跑了快四十分钟结果本地网络抖了一下SSH 连接断了脚本进程跟着一起没了前面四十分钟白跑。那一刻我才真正理解终端复用器存在的意义——它解决的核心问题不是让终端更好看而是让会话与连接解耦。打个比方传统的 SSH 连接就像你打电话给朋友电话一挂聊天就结束了。而 tmux 相当于你建了一个聊天室你人可以随时离开、随时回来聊天室里的人还在继续聊。你的进程跑在 tmux 的会话里而不是跑在你的 SSH 连接里所以连接断了进程照样活着。tmux 的全称是 Terminal Multiplexer终端复用器。它主要提供三个能力第一会话持久化断线不丢进程第二窗口与面板分割一个终端窗口里同时开好几个 shell第三会话共享多个人可以连到同一个会话里看同样的内容。这三个能力里对绝大多数人来说第一个是最刚需的后两个是用了就回不去的效率提升。这篇文章我会从下载安装讲起把不同系统上的安装方式、配置文件怎么写、日常高频操作、以及我踩过的那些坑都讲清楚。不管你是刚接触 Linux 服务器的新手还是已经用了几年但只会tmux new和tmux attach的老用户应该都能从里面找到点有用的东西。2. 各平台安装 tmux 的完整路径2.1 Linux 上的包管理器安装Linux 是 tmux 的主场绝大多数发行版的官方源里都有安装非常简单。但不同发行版的包管理器不一样我把常见的几个列出来。Debian 和 Ubuntu 系列用 aptsudo apt update sudo apt install -y tmuxCentOS、RHEL、Rocky Linux 这些用 yum 或 dnf# CentOS 7 及更早 sudo yum install -y tmux # CentOS 8 / Rocky / Alma sudo dnf install -y tmuxArch 系列用 pacmansudo pacman -S tmux这里有个经验点官方源里的 tmux 版本往往偏旧。比如 Ubuntu 20.04 自带的 tmux 是 3.0a而新版本已经到 3.4 了。新版本在配置语法、弹出窗口popup、以及一些快捷键上有改进。如果你对版本有要求可以考虑从源码编译或者用一些第三方源。但对绝大多数人来说源里的版本完全够用没必要折腾。装完之后验证一下tmux -V # 输出类似 tmux 3.2a2.2 macOS 上的安装选择macOS 上没有自带的 tmux需要用 Homebrew 装brew install tmux如果你还没装 Homebrew先去官网按提示装一下这里不展开。装完之后同样用tmux -V验证。macOS 上有个小细节值得注意系统自带的终端Terminal.app对某些按键组合的支持不太理想比如Ctrlb之后的一些操作可能会和系统快捷键冲突。我个人的建议是配合 iTerm2 使用iTerm2 对 tmux 的兼容性更好甚至内置了 tmux 集成模式。当然这不是必须的用默认终端也能跑。2.3 Windows 上的三种可行方案Windows 上情况稍微复杂一点因为 tmux 本身是 Unix 工具没有原生 Windows 版本。可行的方案有三种。第一种是WSL2这是我最推荐的。装好 WSL2 之后在里面跑一个 Ubuntu然后sudo apt install tmux就行体验和原生 Linux 几乎一样。WSL2 的终端可以用 Windows Terminal配合起来很舒服。第二种是MSYS2 或 Cygwin它们提供了类 Unix 环境里面可以装 tmux。但说实话这种方式下的 tmux 体验一般路径映射、终端渲染都容易出问题我不太推荐。第三种是Git Bash 配合一些替代方案但 Git Bash 本身不带 tmux需要额外折腾性价比不高。所以 Windows 用户直接上 WSL2别犹豫。这是目前最省心、最接近原生体验的方案。2.4 源码编译什么时候值得折腾如果你确实需要最新版本或者你的系统源里没有 tmux那就得源码编译。编译前需要装几个依赖libevent、ncurses有些版本还需要utf8proc。以 Debian/Ubuntu 为例先装依赖sudo apt install -y build-essential libevent-dev libncurses-dev然后下载源码、解压、编译# 假设你已经下载了 tmux-3.4.tar.gz tar -zxvf tmux-3.4.tar.gz cd tmux-3.4 ./configure --prefix/usr/local make -j$(nproc) sudo make install--prefix/usr/local是为了不覆盖系统自带的版本装到/usr/local/bin下。装完之后可能需要hash -r刷新一下命令缓存或者重新开一个终端。提示源码编译最容易出问题的地方是依赖没装全报错通常是找不到event.h或ncurses.h。看到这类报错先检查对应的 dev 包有没有装。3. 配置文件让 tmux 从能用变成好用3.1 配置文件的位置与加载顺序tmux 的配置文件默认叫.tmux.conf放在用户主目录下也就是~/.tmux.conf。它启动时会按顺序读几个位置优先级从高到低大致是命令行-f指定的文件~/.tmux.conf/etc/tmux.conf系统级我建议就用~/.tmux.conf简单直接。改完配置之后不需要重启 tmux在 tmux 里按Ctrlb然后输入:source-file ~/.tmux.conf回车配置就重新加载了。或者更省事在配置里加一个快捷键绑定后面会讲。3.2 一份我用了三年的基础配置下面这份配置是我自己一直在用的去掉了一些花哨的东西保留最实用的部分。你可以直接抄也可以按需删减。# 把前缀键从 Ctrlb 改成 Ctrla # 原因Ctrlb 在有些终端里和翻页冲突Ctrla 更顺手 set -g prefix C-a unbind C-b bind C-a send-prefix # 开启鼠标支持可以点击切换面板、拖动调整大小、滚动 set -g mouse on # 窗口和面板编号从 1 开始而不是 0 set -g base-index 1 setw -g pane-base-index 1 set -g renumber-windows on # 减少 ESC 延迟vim 用户会感谢这一条 set -sg escape-time 10 # 历史滚动缓冲区行数默认 2000 有点少 set -g history-limit 10000 # 用更直观的分割快捷键 # | 竖着分- 横着分 bind | split-window -h -c #{pane_current_path} bind - split-window -v -c #{pane_current_path} # 用 h/j/k/l 在面板间移动和 vim 一致 bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R # 重新加载配置的快捷键前缀 r bind r source-file ~/.tmux.conf \; display 配置已重新加载 # 开启 256 色和真彩色支持 set -g default-terminal screen-256color set -ga terminal-overrides ,xterm-256color:Tc这份配置里我觉得最值得加的是鼠标支持和面板编号从 1 开始。鼠标支持让你可以直接用鼠标点选面板、滚动查看历史对新手极其友好。编号从 1 开始是因为键盘上 1 比 0 好按而且符合直觉。3.3 配置里几个容易踩的坑第一个坑是escape-time。默认值通常是 500 毫秒这意味着你在 tmux 里用 vim按 ESC 退出插入模式后要等半秒才能响应下一个按键。改成 10 毫秒之后vim 用起来就顺滑多了。这个坑我当初找了很久才定位到一直以为是 vim 的问题。第二个坑是真彩色支持。如果你在 tmux 里用 neovim 或者一些主题发现颜色发灰、不对多半是 tmux 没开真彩色。上面配置里的terminal-overrides那一行就是干这个的。但要注意这行只在你的终端本身支持真彩色时才有效如果终端不支持加了也没用。第三个坑是base-index改了之后已有的会话不会自动重编号。也就是说你改配置之前开的会话窗口还是从 0 开始。新开的会话才会生效。这个不算 bug但容易让人困惑。4. 日常高频操作从新建会话到面板管理4.1 会话的创建、断开与恢复tmux 的操作逻辑是前缀键 某个键。默认前缀键是Ctrlb我上面配置改成了Ctrla。下面为了通用我用前缀来指代。新建一个会话tmux new -s work-s work是给会话起个名字叫 work方便后面识别。如果不加-stmux 会自动生成一个数字名字时间长了根本分不清哪个是哪个。强烈建议每次都起名字。在会话里按前缀 d就是 detach也就是断开当前会话但保持它运行。这时候你回到普通终端会话还在后台跑着。想重新连回去tmux attach -t work或者简写tmux a -t work。如果只有一个会话直接tmux a也行。查看当前有哪些会话tmux ls输出类似work: 3 windows (created Mon Jan 15 10:23:45 2024) db: 1 windows (created Mon Jan 15 11:05:12 2024)杀掉一个不需要的会话tmux kill-session -t work或者在会话里按前缀 :然后输入kill-session回车。4.2 窗口与面板一个终端当多个用窗口window和面板pane是 tmux 里两个容易混淆的概念。我的理解是窗口相当于浏览器的标签页面板相当于一个标签页里分屏。新建窗口前缀 c。关闭窗口前缀 会确认。切换窗口前缀 数字或者前缀 n下一个、前缀 p上一个。面板分割默认是前缀 %竖分和前缀 横分。我上面配置改成了前缀 |和前缀 -更直观。分割之后用前缀 方向键或者我配置里的前缀 h/j/k/l在面板间移动。调整面板大小按住前缀不放然后按方向键可以一格一格调整。或者用前缀 z把当前面板最大化再按一次恢复。这个z键我用的频率极高尤其是在小屏幕上临时看一大段输出的时候。关闭面板前缀 x会确认。或者直接在里面输入exit。4.3 复制粘贴与滚动查看tmux 里的复制粘贴和系统的不太一样因为它有自己的缓冲区。默认情况下你直接用鼠标选中文本选的是 tmux 渲染出来的内容复制到系统剪贴板可能不生效取决于终端。我的做法是开启鼠标模式后直接用鼠标拖选然后按终端的复制快捷键。在 iTerm2 里是CmdC在 Windows Terminal 里是CtrlShiftC。这样复制的是终端层面的内容能进系统剪贴板。如果你要用 tmux 自己的复制模式按前缀 [进入然后用方向键或 vim 键移动按空格开始选择回车复制。复制完之后按前缀 ]粘贴。这套流程比较绕我一般不用除非是在没有鼠标的环境里。滚动查看历史开启鼠标后直接滚轮就行。没开鼠标的话前缀 [进入复制模式然后用PageUp/PageDown翻页按q退出。5. 那些让我折腾半天的实际问题5.1 会话里的进程为什么还是被杀了这是最反直觉的一个坑。很多人以为用了 tmux进程就绝对不会被杀。其实不是。tmux 只保证连接断开时进程不受影响但如果服务器重启、或者系统 OOM内存不足杀进程、或者你自己误操作杀了会话进程照样没。我遇到过一次跑一个内存占用比较大的任务结果系统内存不够OOM killer 直接把我的进程干掉了tmux 会话还在但里面的进程没了。这种情况 tmux 救不了你得靠nohup、systemd或者任务队列来兜底。所以正确的理解是tmux 解决的是网络断连这一类问题不解决机器本身出问题这一类问题。两者是不同层面的保障。5.2 嵌套 tmux 时的前缀键冲突有时候你会在本地开一个 tmux然后 SSH 到远程远程又开了一个 tmux。这时候按前缀键到底发给谁默认情况下前缀键发给最外层的 tmux。如果你想发给内层的需要按两次前缀键。比如Ctrla Ctrla d第一个Ctrla被外层吃掉第二个Ctrla传给内层然后d就是内层的 detach。这个机制叫send-prefix。我上面配置里的bind C-a send-prefix就是干这个的。嵌套场景下按两次前缀键就能操作内层习惯就好。5.3 配置文件改了不生效的排查思路改完.tmux.conf发现没效果按这个顺序排查第一确认文件路径对不对。ls -la ~/.tmux.conf看看文件在不在有没有拼错。第二确认有没有重新加载。在 tmux 里按前缀 :输入source-file ~/.tmux.conf看有没有报错。如果报错通常是语法问题比如少了引号、多了空格。第三确认配置项是不是被后面的配置覆盖了。tmux 配置是从上往下读的后面的会覆盖前面的。如果你在文件末尾又写了一遍set -g mouse off那前面的on就白写了。第四有些配置项只对新会话生效比如base-index。已经开着的会话不会变。这种情况只能杀掉重开。5.4 终端显示乱码或颜色异常这个问题的根源通常是TERM环境变量和 tmux 的default-terminal设置不匹配。在 tmux 里输入echo $TERM正常应该输出screen或screen-256color。如果输出的是xterm之类说明 tmux 没接管好。解决办法是在.tmux.conf里明确设置set -g default-terminal screen-256color如果还是不对检查一下你的 shell 配置文件.bashrc或.zshrc里有没有覆盖TERM。有些主题或插件会改这个变量导致冲突。6. 把 tmux 用顺手的几个进阶习惯6.1 给常用会话建立快速连接如果你经常连同一台服务器上的同一个会话可以在本地 shell 里加个别名。比如在~/.bashrc或~/.zshrc里alias twtmux attach -t work || tmux new -s work这行的意思是尝试连接 work 会话如果不存在就新建一个。这样一条命令搞定不用先ls再attach。6.2 用脚本批量管理会话如果你每天开工都要开一堆会话可以写个脚本。比如#!/bin/bash # 检查会话是否存在不存在则创建 tmux has-session -t dev 2/dev/null if [ $? ! 0 ]; then tmux new-session -d -s dev tmux send-keys -t dev cd ~/projects C-m fi tmux has-session -t logs 2/dev/null if [ $? ! 0 ]; then tmux new-session -d -s logs fi tmux attach -t dev这个脚本会确保 dev 和 logs 两个会话存在然后连到 dev。send-keys那行是往会话里发命令C-m相当于回车。这种脚本适合把每天重复的准备工作自动化掉。6.3 会话共享的实用场景tmux 的会话共享功能在结对排查问题时特别好用。两个人 SSH 到同一台机器都 attach 到同一个会话就能看到同样的屏幕一个人操作另一个人实时看。具体做法是第一个人tmux new -s pair第二个人tmux attach -t pair。默认情况下两个人看到的是同一个活动窗口操作会互相影响。如果想各看各的窗口可以前缀 w选择不同的窗口。不过要注意会话共享时两个人的终端尺寸可能不一样tmux 会按较小的那个来渲染可能导致显示错位。这个目前没有完美的解决办法只能尽量让两边终端大小接近。6.4 定期清理僵尸会话用久了之后tmux ls会列出一堆不用的会话占着资源。我一般每周清理一次# 列出所有会话 tmux ls # 杀掉指定会话 tmux kill-session -t 会话名 # 杀掉所有会话慎用 tmux kill-serverkill-server会把所有会话和 tmux 服务一起干掉用之前想清楚。我一般不用这个除非是确定所有会话都不需要了。7. 关于 tmux 我个人的一些体会用了几年 tmux 下来我最大的感受是它的价值不在于功能多而在于它把终端会话这件事变得可靠了。以前跑长任务总是提心吊胆现在开了 tmux 就安心该断网断网该合盖合盖回来tmux a一切照旧。另一个体会是配置不要一次加太多。我见过有人从网上抄了一份几百行的配置结果自己都不知道每个选项是干嘛的出了问题根本没法排查。我的建议是先用默认配置跑一段时间遇到具体的不顺手再针对性加一条慢慢积累成自己的配置。这样每一条配置你都知道它的来龙去脉。最后分享一个小技巧如果你在 tmux 里想快速执行上一条命令不用退出复制模式直接按前缀 :输入send-keys Up Enter就行。这个在写脚本自动化的时候特别有用可以模拟按键序列。当然日常用的话直接按上箭头更简单这只是个知道就好的冷知识。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进