一、Tmux 简介

Tmux‌ 是一款 ‌终端复用器‌(Terminal Multiplexer),允许用户在单个终端窗口中同时管理多个终端会话、窗口和窗格。它的核心功能包括:

  • 会话管理‌:保持长时间运行的进程(如 SSH 连接),断网后仍可恢复。
  • 窗口和窗格‌:将终端分割为多个窗格(Pane)或窗口(Window),提升多任务效率。

对比传统终端,Tmux 解决了长任务依赖终端存活的问题,且提升多任务操作效率。特别是在cp或者mv文件期间,一旦我们的远程连接工具所在的工作电脑出现断网或断电的情况那么传输就会因此中断。

二、核心概念

  1. Session(会话)

  • 定义‌:顶层管理单位,代表一个独立的工作环境(如一个开发项目)。

  • 作用‌:隔离不同任务,长期保存工作进度。

  • 示例‌:

    1
    tmux new -s dev_project  # 创建名为 "dev_project" 的会话
  1. Window(窗口)

  • 定义‌:会话中的二级单位,类似浏览器标签页,用于分隔同一任务的不同阶段。
  • 作用‌:管理相关但独立的操作流(如代码编辑、服务器监控)。
  • 示例‌:
    • Window1:前端开发
    • Window2:后端调试
  1. Pane(窗格)

  • 定义‌:窗口内分割出的子区域,支持并行操作。

  • 作用‌:在单一窗口中同时执行多个命令(如左侧写代码,右侧运行测试)。

  • 示例‌:

    1
    2
    Prefix + %   # 垂直分屏 
    Prefix + " # 水平分屏
  1. 层级关系

​ Session → Window → Pane

  • 比喻‌:
    • Session = 整个项目
    • Window = 项目的不同阶段(开发、测试)
    • Pane = 阶段内的具体操作界面

三、安装 Tmux

  1. Linux

1
2
3
4
5
6
7
8
9
# Ubuntu/Debian
sudo apt update && sudo apt install tmux

# CentOS/RHEL
sudo yum install tmux # 或 sudo dnf install tmux(新版本)

# Arch Linux
sudo pacman -S tmux

  1. MacOS

1
2
# 使用 Homebrew
brew install tmux

四、Tmux基本操作与快捷键

Tmux 大部分操作需先按 前缀键(默认 Ctrl+b),再按功能键。以下所有的前缀键都简称为Prefix

  1. 会话(Session)操作

操作 命令/快捷键 说明
新建会话 tmux new -s <会话名>tmux new 创建指定名称的会话或创建默认会话名
分离当前会话 Prefix + d 退出 Tmux,会话后台运行
列出会话 tmux lsPrefix + s 查看所有会话
恢复会话 tmux attach -t <会话名> 重新接入指定会话
关闭会话 tmux kill-session -t <会话名> 终止指定会话
  1. 窗口(Window)操作

操作 快捷键 说明
新建窗口 Prefix + c 创建新窗口(编号从 0 开始)
切换窗口 Prefix + 0~9 按编号切换窗口
重命名窗口 Prefix + , 自定义窗口名称(如”API调试”)
关闭窗口 Prefix + & 关闭当前窗口(需确认)
窗口列表 Prefix + w 可视化选择窗口
  1. 窗格(Pane)操作

操作 快捷键 说明
垂直分割 Prefix + % 左右分屏(| 状)
水平分割 Prefix + " 上下分屏(— 状)
切换焦点 Prefix + 方向键 按方向移动焦点
关闭窗格 Prefix + x 关闭当前窗格(需确认)
调整大小 Prefix + Ctrl+方向键 按住方向键精细调整
全屏显示 Prefix + z 临时放大当前窗格

五、实用技巧

  1. 同步操作多个窗

  • Ctrl + b: → 输入 setw synchronize-panesEnter (再次输入取消)
  1. 复制模式

  • Ctrl + b[:进入复制模式,选择文本后按 Enter 复制。
  • Ctrl + b]:粘贴已复制内容。
  1. 快速跳转

  • Ctrl + bq:显示窗格编号,按数字键快速跳转。
  1. 重新加载配置

  • Ctrl + b: → 输入 source-file ~/.tmux.confEnter

六、自定义配置

编辑 ~/.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
# 启动鼠标控制
set -g mouse on

# "C-s R" 重载 tmux 配置
bind R source-file ~/.tmux.conf \; display-message "Tmux Config reloaded..."

# 设置 Prefix+y 同步控制所有窗口
bind y setw synchronize-panes

# 窗口重命名
set -w -g allow-rename on
set -w -g automatic-rename on

# 窗口操作默认按键绑定
set -w -g mode-keys vi

# 终端颜色
# 此颜色应当与所使用终端配置一致,当前为 Alacritty
set -g default-terminal "xterm-256color"
# -a: append
set -ga terminal-overrides ",xterm-256color:Tc:clipboard"

# 防止自动关闭 Session
set -g destroy-unattached off

# 颜色
set -g status-bg default
set -g status-fg white

# 刷新时间
set -g status-interval 1

# 对齐方式
set -g status-justify centre

七、脚本分享

分享一个tmux批量ssh服务器的脚本,前提是已经将公钥加到对应的服务器上可以直接ssh登录。

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
#!/bin/bash
# 文件名: tmux-multissh.sh
# 用途:自动创建 Tmux 会话并连接多台主机
# 参数:./tmux-multissh.sh [-l 用户名] [-p 端口] [-n 会话名称] <主机列表文件>
# 示例:./tmux-multissh.sh -l ops -p 22 -n docker hosts.txt

# 检查参数
if [ $# -lt 1 ]; then
tmux
exit 1
fi

# 配置变量
SESSION_NAME="multi_ssh" # 会话名称(默认 multi_ssh)
LAYOUT="tiled" # 布局方式 (tiled, even-horizontal, even-vertical)
SSH_OPTIONS="-o ConnectTimeout=5 -o StrictHostKeyChecking=no" # SSH 连接选项
PORT="22"
PANES_PER_WINDOW=4 # 每个窗口最大面板数
USER="ops"

while getopts ":l:p:n:" opt
do
case $opt in
l)USER=$OPTARG;; # 指定SSH 用户名
p)PORT=$OPTARG;; # 指定SSH 端口
n)SESSION_NAME=$OPTARG;; # 指定会话名称
:) echo "错误: 选项 -$OPTARG 需要参数" >&2; exit 1 ;;
\?) echo "无效选项: -$OPTARG" >&2
echo "用法: $0 [-l 用户名] [-p 端口] [-n 会话名称] <主机列表文件>" >&2
exit 1 ;;
esac
done
HOST_FILE=`echo $* | awk '{print $NF}'` # 主机列表文件路径
shift $((OPTIND -1)) # 移除已解析选项

# 检查必要工具
command -v tmux >/dev/null 2>&1 || { echo "错误: 请先安装 tmux"; exit 1; }

# 读取主机列表
if [ ! -f "$HOST_FILE" ]; then
echo "错误: 主机文件 $HOST_FILE 不存在"
exit 1
fi

# 检查是否已有同名会话
if tmux has-session -t "$SESSION_NAME" 2>/dev/null; then
echo "错误: 会话 $SESSION_NAME 已存在,请先关闭或使用不同名称"
exit 1
fi

readarray -t HOSTS < <(grep -v '^[[:space:]]*#' "$HOST_FILE" | grep -v '^[[:space:]]*$')

# 创建新会话(第一个窗口)
tmux new-session -d -s "$SESSION_NAME" -n "SSH-Panel-0"
tmux send-keys -t "$SESSION_NAME:0" "ssh ${SSH_OPTIONS} -p $PORT $USER@$(head -n 1 "$HOST_FILE")" C-m


# 检查主机列表是否为空
HOSTS_COUNT=${#HOSTS[@]}
[ $HOSTS_COUNT -eq 0 ] && { echo "错误: 主机列表为空"; exit 1; }

# 为剩余主机创建连接面板
for ((i=1; i<HOSTS_COUNT; i++)); do
# 计算窗口编号(每PANES_PER_WINDOW个主机一个窗口)
window=$((i / PANES_PER_WINDOW))
pane=$((i % PANES_PER_WINDOW))

# 创建新窗口(当需要时)
if [ $pane -eq 0 ]; then
tmux new-window -t "$SESSION_NAME:$window" -n "SSH-Panel-$window"
else
tmux split-window -t "$SESSION_NAME:$window" -h
fi

# 发送SSH连接命令并调整布局
tmux send-keys -t "$SESSION_NAME:$window.$pane" \
"ssh ${SSH_OPTIONS} -p $PORT $USER@${HOSTS[$i]}" C-m
tmux select-layout -t "$SESSION_NAME:$window" "$LAYOUT"
done

# 设置初始窗口和焦点
tmux select-window -t "$SESSION_NAME:0"
tmux select-pane -t 0
tmux setw -t "$SESSION_NAME" synchronize-panes off

# 用户交互
read -p "是否立即附加到会话?[Y/n] " -n 1 -r
echo
if [[ $REPLY =~ ^[Nn]$ ]]; then
echo "会话已在后台运行,附加命令: tmux attach -t $SESSION_NAME"
else
tmux attach -t "$SESSION_NAME"
fi

可以做一个简单别名,更方便执行。将下文写入到

1
2
3
4
5
6
7
# 写入自定义别名
vim .bashrc

alias tmuxa='./tmux-multissh.sh'

# 保存退出后重新加载配置文件
source ~/.bashrc

这样就可以更方便的同时ssh到多台服务器,例如:

image-20250313191539703