tmux 与 screen 全面对比及 tmux 深度使用指南

tmux 与 screen 全面对比及 tmux 深度使用指南

什么是终端复用器?

终端复用器(Terminal Multiplexer)让你在一个终端窗口中同时管理多个会话。它可以:

  • 在后台持久运行程序,关掉终端也不会中断
  • 在一个窗口里分屏操作(水平/垂直分割)
  • 断开后重新连接,像什么都没发生过
  • 多人同时 attach 到同一个会话,实现结对编程

最主流的两个选择:GNU Screentmux

历史渊源

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
# macOS
brew install tmux

# Ubuntu/Debian
sudo apt install tmux

# CentOS/RHEL/Fedora
sudo dnf install tmux

# Arch Linux
sudo pacman -S tmux

# 从源码编译
git clone https://github.com/tmux/tmux.git
cd tmux
sh autogen.sh
./configure && make && sudo make install

验证安装:

1
tmux -V   # 输出类似 tmux 3.5

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
# 创建并 attach 新会话
tmux new -s mysession

# 创建会话但不 attach
tmux new -s mysession -d

# 列出所有会话
tmux ls

# attach 到已有会话
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 09 切换到第 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 一样浏览和复制终端历史内容。

1
Prefix [    # 进入复制模式

在复制模式下(默认 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
# ==================== 基础设置 ====================

# 修改前缀键为 Ctrl+a(和 screen 一致,也更顺手)
set -g prefix C-a
unbind C-b # 解除默认前缀
bind C-a send-prefix # 双击前缀发送前缀本身

# 设置 TERM
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*256col*:Tc" # 开启 true color

# 鼠标支持(滚轮、点击、拖拽调整窗格)
set -g mouse on

# 设置超时(减少延迟)
set -g escape-time 10

# 设置历史滚动行数
set -g history-limit 50000

# 启用 vi 风格键位
set-window-option -g mode-keys vi
set -g status-keys vi

# 索引从 1 开始(而不是 0)
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!"

# 用 Ctrl+hjkl 快速切换窗格(Vim 风格)
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

# 用 Shift+方向键调整窗格大小
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

# 关闭 beep
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
# 或在 tmux 内按 Prefix + r

进阶技巧

1. tmux-resurrect + tmux-continuum:会话持久化

这两个插件让 tmux 做到”重启不丢会话”。

1
2
# 安装 TPM(Tmux Plugin Manager)
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
# TPM 插件管理器
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'

# vim/neovim 会话恢复
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
# A 创建会话
tmux new -s pair-programming

# B attach 到同一会话(同一台机器或 SSH)
tmux attach -t pair-programming

设置不同光标颜色区分两人:

1
2
3
4
5
# A 的窗口
tmux set -g window-style 'fg=default,bg=default'
tmux set -g window-active-style 'fg=default,bg=default'

# B 的窗口(光标会不同)

3. 结合 Vim/Neovim

使用 Vim 风格的键盘绑定切换 tmux 窗格和 Vim 窗口:

1
2
3
4
5
# ~/.tmux.conf - 用 Ctrl+hjkl 切换窗格
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
" ~/.vimrc - 在终端模式下用相同键切换 Vim 窗口
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

" 普通模式下用 Ctrl+hjkl 切换
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
# dev-session.sh — 一键创建开发环境

session="dev"

tmux new-session -d -s $session

# 窗口 1:编辑器(vim)
tmux rename-window -t $session:1 'editor'
tmux send-keys -t $session:1 'vim' Enter

# 窗口 2:终端(分三个 pane)
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

# 窗口 3:日志监控
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)

1
2
Prefix : copy-mode  # 或者 Prefix [
# 然后按 / 输入搜索词,n/N 上下翻

6. 粘贴缓冲区管理

1
2
3
4
Prefix : list-buffers   # 列出所有 buffer
Prefix : choose-buffer # 交互式选择 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
# 在当前目录打开新 pane
Prefix !

# 执行一次命令就关闭
bind-key -n M-x command-prompt -p "Run:" "run-shell \"%%\""

9. 嵌套 tmux(在 tmux 里再开 tmux)

如果在远程服务器里也用了 tmux,需要发送 Prefix 到内层:

1
2
# 按两次 Prefix 发送一次 Prefix 到内层
bind C-a send-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
# 终端模拟器需要支持(iTerm2、Kitty、Alacritty 都支持)
# ~/.tmux.conf 加入:
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",*256col*:Tc"

验证:

1
2
# 在 tmux 内运行
curl -s https://gist.githubusercontent.com/lifepillar/09a44b8cf0f9397465614e622979107f/raw/24-bit-color.sh | bash

Q: 如何让 tmux 自动 attach 到上次的会话?

1
2
3
4
# ~/.zshrc 或 ~/.bashrc 加入
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,之后每一天的工作效率都会有肉眼可见的提升。