Appearance
03|tmux 会话管理
在服务器上跑一个备份,预计要半小时。SSH 连着等结果,结果笔记本一合盖、VPN 一断,SSH 掉了——再连上去,备份进程已经没了,得从头再来。
原因:SSH 断开后,原本依附在这个连接上的 shell 会收到一个"挂起"信号(SIGHUP),把前台进程都杀掉。tmux 解决这个——它把会话留在服务器上,SSH 只是"借来看一眼",断了重连任务还在跑。
一、工作原理
SSH 是客户端到服务器的加密通道。通道断了,里面的 shell 就没了。tmux 在服务器上启动独立的会话进程,SSH 只是"借来看一眼":
本地终端 → SSH → 服务器 → tmux session → shell / 命令 / 程序tmux 跑在 SSH 连接之外。 SSH 只是远程操控 tmux 的工具,连接断了,tmux 还在服务器上活着。
三个概念
| 概念 | 含义 | 类比 |
|---|---|---|
| session | 一个独立的工作区 | 一个项目或一次变更操作 |
| window | session 内的标签页 | 浏览器标签,每个跑不同终端 |
| pane | window 内的分屏 | 同一窗口切成上下/左右两块 |
对运维来说,tmux 最核心的能力不是分屏,是会话持久化。 升级、迁移、批量脚本在 tmux 里跑,至少不用怕断网。
二、安装与基础
bash
# RHEL / CentOS / Rocky
yum install tmux -y
# Debian / Ubuntu
apt install tmux -y
tmux -V # 验证版本创建命名会话
bash
tmux new -s ops-s 给会话起名字。多个会话同时存在时,prod-change 比 2 好用得多。
退出与恢复
| 操作 | 命令或快捷键 | 说明 |
|---|---|---|
| 临时离开(detach) | Ctrl+b 再按 d | 程序继续跑,会话保留 |
| 查看所有会话 | tmux ls | 列出 session 列表 |
| 恢复会话 | tmux attach -t ops | 回到之前的会话 |
| 强制接管 | tmux attach -d -t ops | 踢掉其他客户端后接管 |
detach(Ctrl+b d)和 exit(Ctrl+d / exit)是两回事。 detach 暂时离开但保留会话;exit 真的退出 shell,会关掉 tmux 窗口。
三、session 管理
一段典型用法:
bash
# 新建会话
tmux new -s prod-change
# 执行变更
./deploy.sh
# 下班回家 → detach(Ctrl+b d)到家 SSH 回服务器:
bash
tmux attach -t prod-change
# 看到的是 deploy.sh 的完整输出检查是否已在 tmux 中
bash
echo "$TMUX" # 有值说明当前已在 tmux 中如果在 tmux 内部再 tmux new,会变成"tmux 嵌套",快捷键出问题。建议先 detach,再切到别的 session。
session 常用操作
| 操作 | 快捷键或命令 |
|---|---|
| detach | Ctrl+b d |
| 重命名 session | Ctrl+b $ |
| 切换 session | Ctrl+b s(列表) |
| 关闭 session | tmux kill-session -t ops |
四、window 管理
一个 session 可包含多个 window,每个做不同的事——窗 0 跑命令,窗 1 看日志,窗 2 连数据库。
bash
tmux new-window -n log # 新建 window,命名 log
tmux new-window -n tcpdump把 window 名改成 log、tcpdump、app-status 等短名,比默认 bash 直观得多。
| 操作 | 快捷键 |
|---|---|
| 新建 window | Ctrl+b c |
| 重命名 | Ctrl+b , |
| 下一个/上一个 | Ctrl+b n / Ctrl+b p |
| 跳到指定窗 | Ctrl+b 0-9 |
| 关闭 window | Ctrl+b & |
五、pane 分屏
同一窗口中切出多个分屏,同时看日志和执行命令。
| 操作 | 快捷键 |
|---|---|
| 左右分屏 | Ctrl+b % |
| 上下分屏 | Ctrl+b " |
| 切换 pane | Ctrl+b 方向键 |
| 关闭 pane | Ctrl+b x |
| 最大化/还原 | Ctrl+b z |
| 切换布局 | Ctrl+b 空格 |
典型排查场景
bash
# pane 1:持续看日志
journalctl -u nginx -f
# pane 2:反复请求接口
watch -n 2 'curl -fsS http://127.0.0.1/healthz || echo failed'分屏超过 4 个后可读性明显下降。 此时多开 window 比继续切分更合理。
六、复制模式与配置
查看历史输出
bash
# 进入复制模式
Ctrl+b [
# 上下翻 / PageUp/PageDown / /搜索
# 按 q 退出开启鼠标支持
tmux
# ~/.tmux.conf
set -g mouse on # 滚动翻历史、拖拽 pane
set -g history-limit 50000 # 单 pane 历史行数(默认 2000)
set -g base-index 1 # window 从 1 编号
setw -g pane-base-index 1 # pane 从 1 编号bash
tmux source-file ~/.tmux.conf # 重新加载服务器上配置越精简越好
服务器 tmux 不适合堆插件和复杂配置。 朴素配置在任何一台服务器上都能工作,才是救场工具该有的样子。
七、长任务执行
可能导致异常中止的任务应该在 tmux 里跑:
| 任务类型 | 原因 |
|---|---|
| 数据迁移 | 时间长,不能因 SSH 断开就退出 |
| 应用发布 | 需要边执行边看日志边调整 |
| 批量巡检 | 多轮命令,结果保留在 pane 中回头翻 |
| 抓包 | 可能跑很久,中途断开不能丢 |
| 数据库备份 | 长,失败后要看现场输出 |
保存长任务输出
仅靠 tmux 滚动缓冲区不够稳——缓冲区被新输出冲掉后会丢失日志。
bash
# tee 同时显示和存档
./deploy.sh 2>&1 | tee deploy-$(date +%F-%H%M%S).logtee 把输出分成两份——一份到终端,一份写入文件。事后复盘有据可查。
备份示例
bash
tmux new -s backup
mkdir -p /backup/mysql
mysqldump \
--single-transaction \
--routines \
--triggers \
app_db \
> /backup/mysql/app_db-$(date +%F).sql八、断线恢复
SSH 意外断开后:
bash
tmux ls # 查看会话
tmux attach -t ops # 恢复会话被占用
如果有残留连接占着会话:
bash
tmux attach -d -t ops # 踢掉旧连接,接管多人共用同系统用户时:
bash
tmux list-clients -t ops # 先看谁连着的,避免误伤看不到会话
no server running on /tmp/tmux-1000/defaulttmux server 的 socket 在用户自己的临时目录下——root 创建的 tmux,普通用户看不到;反之亦然。 确认操作者身份一致。
九、screen 备选
老系统没 tmux 但通常有 screen:
bash
screen -S ops # 创建
Ctrl+a d # detach
screen -ls # 查看
screen -r ops # 恢复新环境用 tmux,screen 作为老机器上的备选。
十、速查表
| 操作 | 命令/快捷键 |
|---|---|
| 新建会话 | tmux new -s <name> |
| 查看会话 | tmux ls |
| 恢复 | tmux attach -t <name> |
| 强制接管 | tmux attach -d -t <name> |
| 离开(保留) | Ctrl+b d |
| 新建 window | Ctrl+b c |
| 重命名 window | Ctrl+b , |
| 左右分屏 | Ctrl+b % |
| 上下分屏 | Ctrl+b " |
| 关闭 pane | Ctrl+b x |
| 最大化 pane | Ctrl+b z |
| 进复制模式 | Ctrl+b [ |
| 关闭会话 | tmux kill-session -t <name> |
| 重命名会话 | Ctrl+b $ |
| 切换会话 | Ctrl+b s |