tmux 与 screen 全面对比及 tmux 深度使用指南
什么是终端复用器?
终端复用器(Terminal Multiplexer)让你在一个终端窗口中同时管理多个会话。它可以:
- 在后台持久运行程序,关掉终端也不会中断
- 在一个窗口里分屏操作(水平/垂直分割)
- 断开后重新连接,像什么都没发生过
- 多人同时 attach 到同一个会话,实现结对编程
最主流的两个选择:GNU Screen 和 tmux。
历史渊源
Screen 诞生于 1987 年,GNU 项目的一部分,是终端复用器的元老。三十多年来几乎每个 Linux 发行版都默认自带。
tmux 诞生于 2007 年,作者是 Nicholas Marriott(也是 OpenBSD 的 tmux 开发者)。当时 screen 的代码已非常陈旧,维护困难,tmux 从头设计,代码更现代、更清晰。
Screen vs tmux 对比
| 特性 |
Screen |
tmux |
| 首次发布 |
1987 |
2007 |
| 配置文件 |
~/.screenrc |
~/.tmux.conf |
| 默认前缀键 |
Ctrl+a |
Ctrl+b |
| 垂直分屏 |
需手动编译补丁 |
原生支持 |
| 水平分屏 |
原生支持 |
原生支持 |
| 状态栏 |
默认关闭,需配置 |
默认自带,功能强大 |
| 256 色 |
需配置 screen-256color |
默认支持 |
| true color |
不支持 |
支持 |
| 复制模式 |
vi/emacs 可选 |
vi/emacs 可选 |
| 脚本化控制 |
有限 |
send-keys 等非常灵活 |
| 插件生态 |
基本没有 |
TPM、tmux-resurrect 等 |
| 会话持久化 |
无 |
tmux-resurrect 插件 |
| buffer 管理 |
有 |
更强大 |
| 跨平台 |
几乎全平台 |
几乎全平台 |
| 代码质量 |
历史遗留,C 代码 |
现代,BSD 许可证 |
核心结论:如果只在最基础的场景下使用(单窗口、简单 detach/attach),两者差别不大。但如果你需要分屏、定制化、脚本集成,tmux 全面胜出。
tmux 安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| brew install tmux
sudo apt install tmux
sudo dnf install tmux
sudo pacman -S tmux
git clone https://github.com/tmux/tmux.git cd tmux sh autogen.sh ./configure && make && sudo make install
|
验证安装:
tmux 核心概念
tmux 采用三层结构:
1 2 3 4
| tmux ├── Session(会话) ← 最外层,可类比"项目" │ └── Window(窗口) ← 可类比"标签页" │ └── Pane(窗格) ← 可类比"分屏区域"
|
Session:一个独立的工作环境。你可以有多个 session,每个 session 管理一组 window。
Window:对应传统终端的一个”标签页”。每个 window 占据整个终端。
Pane:window 内的分割区域,可以水平或垂直拆分成多个 pane。
交互的核心是 Prefix Key(前缀键),默认为 Ctrl+b。所有快捷键都以前缀键开头。
Session 管理
命令行操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| tmux new -s mysession
tmux new -s mysession -d
tmux ls
tmux attach -t mysession
tmux rename-session -t mysession newsession
tmux kill-session -t mysession
tmux kill-server
|
会话内快捷键
| 快捷键 |
功能 |
Prefix d |
从当前会话分离(detach) |
Prefix s |
交互式选择会话 |
Prefix $ |
重命名当前会话 |
Prefix ( |
切换到上一个会话 |
Prefix ) |
切换到下一个会话 |
Prefix L |
切换到最后一个使用的会话 |
最佳实践:给会话起有意义的名字
1 2 3 4 5 6 7 8
| tmux new -s 0 tmux new -s 1
tmux new -s project-frontend tmux new -s server-debug tmux new -s blog-editing
|
Window 管理
| 快捷键 |
功能 |
Prefix c |
创建新窗口 |
Prefix , |
重命名当前窗口 |
Prefix w |
交互式选择窗口 |
Prefix p |
上一个窗口 |
Prefix n |
下一个窗口 |
Prefix 0–9 |
切换到第 N 个窗口 |
Prefix l |
切换到上一个活跃窗口 |
Prefix & |
关闭当前窗口 |
Prefix . |
移动当前窗口(输入目标编号) |
Prefix f |
按关键字搜索窗口标题 |
Pane 管理
这是 tmux 相比 screen 最大的优势——原生、灵活的分屏。
创建窗格
| 快捷键 |
功能 |
Prefix % |
垂直分屏(左右分割) |
Prefix " |
水平分屏(上下分割) |
窗格间导航
| 快捷键 |
功能 |
Prefix o |
切换到下一个窗格(循环) |
Prefix ↑/↓/←/→ |
按方向切换到相邻窗格 |
Prefix ; |
切换到上一个活跃窗格 |
Prefix q |
显示窗格编号,按编号跳转 |
Prefix { |
当前窗格左移 |
Prefix } |
当前窗格右移 |
窗格大小调整
| 快捷键 |
功能 |
Prefix Ctrl+↑/↓/←/→ |
按方向调整当前窗格大小 |
Prefix Alt+↑/↓/←/→ |
按 5 行/列调整 |
Prefix z |
当前窗格全屏/恢复 |
Prefix space |
切换预置布局(even-horizontal, even-vertical, main-horizontal, main-vertical, tiled) |
窗格操作
| 快捷键 |
功能 |
Prefix x |
关闭当前窗格 |
Prefix ! |
将当前窗格弹出为独立窗口 |
Prefix Ctrl+o |
所有窗格向前旋转 |
Prefix Alt+o |
所有窗格向后旋转 |
同步输入
在多个 pane 中同时输入相同命令——非常适合批量操作多台服务器:
1 2 3
| Prefix : setw synchronize-panes on Prefix : setw synchronize-panes off
|
复制模式(Copy Mode)
tmux 的复制模式让你像用 Vim/Emacs 一样浏览和复制终端历史内容。
在复制模式下(默认 EMACS 键位,可改为 vi):
| vi 键位 |
emacs 键位 |
功能 |
h/j/k/l |
C-b/C-n/C-p/C-f |
移动光标 |
w/b |
M-f/M-b |
按词移动 |
Ctrl-u/Ctrl-d |
Ctrl-u/Ctrl-d |
半屏滚动 |
gg/G |
M-< / M-> |
到开头/末尾 |
v |
Ctrl-space |
开始选中 |
y |
Ctrl-w |
复制选中内容 |
q |
Escape |
退出复制模式 |
粘贴:Prefix ]
配置 tmux(~/.tmux.conf)
tmux 的配置文件默认放在 ~/.tmux.conf(或 ~/.config/tmux/tmux.conf)。
以下是一份完整的生产级配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
|
set -g prefix C-a unbind C-b bind C-a send-prefix
set -g default-terminal "tmux-256color" set -ga terminal-overrides ",*256col*:Tc"
set -g mouse on
set -g escape-time 10
set -g history-limit 50000
set-window-option -g mode-keys vi set -g status-keys vi
set -g base-index 1 setw -g pane-base-index 1
set -g renumber-windows on
setw -g automatic-rename off set-option -g allow-rename off
bind | split-window -h -c "#{pane_current_path}" bind - split-window -v -c "#{pane_current_path}"
bind r source-file ~/.tmux.conf \; display-message "Config reloaded!"
bind -n C-h select-pane -L bind -n C-j select-pane -D bind -n C-k select-pane -U bind -n C-l select-pane -R
bind -n S-Left resize-pane -L 5 bind -n S-Right resize-pane -R 5 bind -n S-Up resize-pane -U 5 bind -n S-Down resize-pane -D 5
bind R source-file ~/.tmux.conf
bind-key -n M-1 select-window -t 1 bind-key -n M-2 select-window -t 2 bind-key -n M-3 select-window -t 3 bind-key -n M-4 select-window -t 4 bind-key -n M-5 select-window -t 5
bind C-c new-window -c "#{pane_current_path}" bind X kill-pane
set -g status-position top set -g status-interval 5
set -g status-style bg=black,fg=white
set -g status-left "#[fg=black,bg=green] #S " set -g status-left-style fg=green,bold
setw -g window-status-format " #I:#W " setw -g window-status-current-format "#[fg=white,bg=blue] #I:#W " setw -g window-status-current-style bg=blue,fg=white setw -g window-status-separator " "
set -g status-right "#[fg=white,bg=black] %Y-%m-%d %H:%M " set -g status-right-style fg=white,bg=black
setw -g monitor-activity on set -g visual-activity on
set -g pane-border-style fg=brightblack set -g pane-active-border-style fg=cyan
set -g set-titles on set -g set-titles-string "#T"
set -g focus-events on
set -g bell-action none
bind c new-window -c "#{pane_current_path}" bind % split-window -h -c "#{pane_current_path}" bind '"' split-window -v -c "#{pane_current_path}"
bind-key L run-shell "tmux list-windows -a -F '#{window_name} #{window_layout}' > ~/.tmux-layout" bind-key M run-shell "cat ~/.tmux-layout | while read name layout; do tmux select-window -t \"$name\" && tmux select-layout \"$layout\"; done"
|
配置修改后,重新加载:
1 2
| tmux source-file ~/.tmux.conf
|
进阶技巧
1. tmux-resurrect + tmux-continuum:会话持久化
这两个插件让 tmux 做到”重启不丢会话”。
1 2
| git clone https://github.com/tmux-plugins/tpm ~/.config/tmux/plugins/tpm
|
在 ~/.tmux.conf 添加:
1 2 3 4 5 6 7 8 9 10 11 12 13
| set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-resurrect' set -g @plugin 'tmux-plugins/tmux-continuum'
set -g @resurrect-capture-pane-contents 'on' set -g @continuum-restore 'on'
set -g @resurrect-strategy-vim 'session'
run '~/.config/tmux/plugins/tpm/tpm'
|
重启 tmux 后按 Prefix + I(大写 I)安装插件。
用法:
Prefix Ctrl+s — 手动保存会话
Prefix Ctrl+r — 手动恢复会话
- tmux-continuum 每 15 分钟自动保存一次
2. 结对编程(Pair Programming)
tmux 天生支持多人同时 attach 到同一个会话。两人看到的是同一个界面,共享输入。
1 2 3 4 5
| tmux new -s pair-programming
tmux attach -t pair-programming
|
设置不同光标颜色区分两人:
1 2 3 4 5
| tmux set -g window-style 'fg=default,bg=default' tmux set -g window-active-style 'fg=default,bg=default'
|
3. 结合 Vim/Neovim
使用 Vim 风格的键盘绑定切换 tmux 窗格和 Vim 窗口:
1 2 3 4 5
| bind -n C-h select-pane -L bind -n C-j select-pane -D bind -n C-k select-pane -U bind -n C-l select-pane -R
|
1 2 3 4 5 6 7 8 9 10 11
| tnoremap <C-h> <C-\><C-n><C-w>h tnoremap <C-j> <C-\><C-n><C-w>j tnoremap <C-k> <C-\><C-n><C-w>k tnoremap <C-l> <C-\><C-n><C-w>l
nnoremap <C-h> <C-w>h nnoremap <C-j> <C-w>j nnoremap <C-k> <C-w>k nnoremap <C-l> <C-w>l
|
4. 命令行脚本化
用 tmux 创建预定义的工作布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #!/bin/bash
session="dev"
tmux new-session -d -s $session
tmux rename-window -t $session:1 'editor' tmux send-keys -t $session:1 'vim' Enter
tmux new-window -t $session -n 'terminal' tmux split-window -h -t $session:2 tmux split-window -v -t $session:2.1 tmux send-keys -t $session:2.1 'npm run dev' Enter tmux send-keys -t $session:2.2 'git status' Enter tmux send-keys -t $session:2.3 'htop' Enter
tmux new-window -t $session -n 'logs' tmux send-keys -t $session:3 'tail -f /var/log/nginx/access.log' Enter
tmux attach -t $session
|
5. 在 pane 中搜索(类似 grep)
6. 粘贴缓冲区管理
1 2 3 4
| Prefix : list-buffers Prefix : choose-buffer Prefix = Prefix
|
7. 监控模式
1 2 3 4 5 6 7 8
| Prefix : setw monitor-activity on
Prefix : setw silent on
Prefix : setw window-status-activity-style fg=yellow
|
8. 快速创建临时 pane
1 2 3 4 5
| Prefix !
bind-key -n M-x command-prompt -p "Run:" "run-shell \"%%\""
|
9. 嵌套 tmux(在 tmux 里再开 tmux)
如果在远程服务器里也用了 tmux,需要发送 Prefix 到内层:
或者临时把外层 prefix 改为别的键。
10. 图形化查看会话
1
| tmux list-sessions -F "#S: #{session_windows} windows [#{session_width}x#{session_height}] (#{session_created_string})"
|
常见问题
Q: tmux 和 terminal 的 256 色 / true color
1 2 3 4
|
set -g default-terminal "tmux-256color" set -ga terminal-overrides ",*256col*:Tc"
|
验证:
1 2
| curl -s https://gist.githubusercontent.com/lifepillar/09a44b8cf0f9397465614e622979107f/raw/24-bit-color.sh | bash
|
Q: 如何让 tmux 自动 attach 到上次的会话?
1 2 3 4
| if [[ -z "$TMUX" && -n "$(tmux list-sessions 2>/dev/null)" ]]; then tmux attach-session -t "$(tmux list-sessions -F '#{session_name}' | fzf)" fi
|
Q: 如何让 pane 继承当前目录?
在配置里已经做了——所有分屏和新建窗口命令都加了 -c "#{pane_current_path}" 参数。
总结
| 使用场景 |
推荐 |
| 需要一个稳定的远程会话保持 |
两者均可,Screen 够用 |
| 需要分屏、多窗口操作 |
tmux |
| 长期运行的服务器无交互任务 |
Screen 更轻量 |
| 需要 vim 风格的 pane 导航 |
tmux |
| 需要会话状态保存/恢复 |
tmux + tmux-resurrect |
| 需要在老旧系统上用 |
Screen(默认自带) |
| 需要现代化配置和插件生态 |
tmux |
如果你刚开始接触终端复用器,直接从 tmux 入手。它学习曲线比 screen 稍陡,但这篇文章覆盖的知识点足够你从入门到精通。花一天时间配好 .tmux.conf,之后每一天的工作效率都会有肉眼可见的提升。