tmux —— 会话保持与分屏协作

运维工具手册 04-文本处理 5.3 KB 原文

tmux —— 会话保持与分屏协作

分类:04 文本处理(终端效率) 适用:全平台(tmux 3.x) 一句话:SSH 断了任务还在跑,一个终端里开多个窗格,还能多人同看一个会话。

1. 它解决什么问题

  • 跑长任务(备份、编译、数据导入)时 SSH 断开,进程被 SIGHUP 杀掉。
  • 一边看日志一边敲命令,反复切换窗口。
  • 远程协助同事,让他看到你的终端操作。
  • 服务器上没有图形界面,需要多路并行。

替代品:screen(更老,功能少)、byobu(tmux 的封装)、zellij(新式)。

2. 安装

apt install -y tmux
dnf install -y tmux
apk add tmux

3. 会话管理(核心)

tmux                        # 新建匿名会话
tmux new -s work            # 新建命名会话
tmux new -s work -d         # 后台新建(不切换进去)
tmux ls                     # 列出会话
tmux attach -t work         # 接入
tmux a                      # 接入最近一个
tmux a -t work              # 简写
tmux kill-session -t work   # 杀掉会话
tmux kill-server            # 杀掉所有会话(⚠️)
tmux rename-session -t old new

在会话内:

快捷键 作用
Ctrl-b d 分离(detach),会话继续跑
Ctrl-b $ 重命名会话
Ctrl-b s 会话列表中选择
Ctrl-b ( / ) 切到上/下一个会话

Ctrl-b 是默认前缀键(prefix),下面写作 C-b。所有快捷键都是先按 C-b 松开,再按功能键。

4. 窗口(window)

C-b c            # 新建窗口
C-b ,            # 重命名窗口
C-b n / p        # 下一个 / 上一个
C-b 0-9          # 切到第 n 个
C-b w            # 窗口列表
C-b &            # 关闭当前窗口(会确认)
C-b l            # 上次使用的窗口

命令行操作:

tmux new-window -n logs 'tail -f /var/log/nginx/error.log'
tmux list-windows -t work
tmux select-window -t work:2

5. 窗格(pane)

C-b %            # 左右分屏
C-b "            # 上下分屏
C-b 方向键       # 切换窗格
C-b o            # 循环切换
C-b z            # 当前窗格最大化/还原(超好用)
C-b x            # 关闭窗格
C-b !            # 把窗格拆成独立窗口
C-b { / }        # 与相邻窗格交换位置
C-b 空格         # 切换布局
C-b q            # 显示窗格编号
C-b Alt+方向     # 调整窗格大小

6. 滚动与复制

C-b [            # 进入复制模式(可上下翻页)
# 复制模式内:
#   方向键/PgUp/PgDn 移动
#   Space 开始选择,Enter 复制并退出
#   q 退出
C-b ]            # 粘贴
C-b ~            # 显示最近的消息(调试用)

开启鼠标(在 ~/.tmux.conf):

set -g mouse on

开启后可以直接滚轮翻页、拖拽选中、点击切窗格。

与系统剪贴板互通(Linux + X11/Wayland):

set -g set-clipboard on
# 或者复制时调用 xclip
bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "xclip -i -selection clipboard"

7. 常用配置 ~/.tmux.conf

# 前缀改为 Ctrl-a(更顺手,注意与 screen/bash 冲突)
set -g prefix C-a
unbind C-b
bind C-a send-prefix

# 从 1 开始编号,符合直觉
set -g base-index 1
setw -g pane-base-index 1

# 鼠标
set -g mouse on

# 历史行数
set -g history-limit 50000

# 关闭时自动重排窗口编号
set -g renumber-windows on

# 更快的按键响应(vim 用户)
set -sg escape-time 10

# 状态栏
set -g status-interval 5
set -g status-left "[#S] "
set -g status-right "%Y-%m-%d %H:%M"

# 分屏快捷键更顺手(| 和 -)
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

# 用 vim 键位在复制模式移动
setw -g mode-keys vi

重载配置:

tmux source-file ~/.tmux.conf

8. 脚本化与自动化

# 一条命令搭好排障布局
tmux new-session -d -s debug -n monitor
tmux split-window -h -t debug
tmux split-window -v -t debug:0.1
tmux send-keys -t debug:0.0 'top' C-m
tmux send-keys -t debug:0.1 'tail -f /var/log/app/error.log' C-m
tmux send-keys -t debug:0.2 'watch -n2 "ss -s"' C-m
tmux attach -t debug

常用命令:

命令 作用
send-keys -t <target> 'cmd' C-m 在指定窗格执行命令
capture-pane -t <target> -p 抓取窗格当前内容(可用于日志留存)
capture-pane -t <target> -p -S -1000 抓最近 1000 行
pipe-pane -t <target> -o 'cat >> /tmp/pane.log' 把输出持续写入文件
respawn-pane -k -t <target> 'cmd' 重启窗格内进程
set-option -t <target> remain-on-exit on 进程退出后保留窗格,便于看报错

9. 实战场景

9.1 长任务防断线

tmux new -s import
# 在会话里执行
mysql -u root -p db < big_dump.sql
# 觉得要断网:C-b d 分离
# 之后回来
tmux a -t import

9.2 多人共享同一会话(远程协助)

# A 创建会话
tmux new -s pair

# B 通过 SSH 连同一台机器
tmux attach -t pair

两人看到同一个屏幕,输入会互相干扰。要只读观察,用 attach -r:

tmux attach -r -t pair      # 只读模式

更规范的协作可以用 wemux 或 tmate(走公网中继)。

9.3 排障四分屏

tmux new -s t -d
tmux split-window -h -t t
tmux split-window -v -t t:0.0
tmux split-window -v -t t:0.2
tmux send-keys -t t:0.0 'top' C-m
tmux send-keys -t t:0.1 'iostat -x 1' C-m
tmux send-keys -t t:0.2 'tail -f /var/log/messages' C-m
tmux send-keys -t t:0.3 'watch -n 1 "ss -s"' C-m
tmux attach -t t

9.4 留存窗格输出作为证据

tmux pipe-pane -t work:0.0 -o 'cat >> /tmp/session-$(date +%F).log'
# 结束后
tmux pipe-pane -t work:0.0        # 停止

9.5 开机自动拉起会话

# crontab
@reboot tmux new-session -d -s monitor 'bash /opt/scripts/monitor.sh'

10. 常见坑

  1. C-b 被其他程序占用:Emacs、screen 也用 C-b,改前缀为 C-a 或 C-\。
  2. 嵌套 tmux:在 tmux 里再 ssh 到一台机器又开 tmux,内层要用 C-b C-b 发前缀。
  3. 分离后进程被杀:通常是脚本里 exec 或进程不处理 SIGHUP;tmux 本身不会杀会话内进程。
  4. 重启机器会话全丢:tmux 不持久化,需要 tmux-resurrect / tmux-continuum 插件。
  5. 复制到系统剪贴板失败:需要 xclip/wl-copy,且 SSH 场景只能依赖终端自身的选中复制。
  6. mouse on 影响选中:开启后按住 Shift 才是终端原生选择。
  7. 状态栏中文乱码:终端 locale 与字体问题,不是 tmux 配置问题。
  8. tmux ls 显示 (attached) 但仍占用:说明有客户端没正常断开,tmux attach -d 强制踢掉。
  9. kill-server 会杀掉所有会话,包括同事在用的,执行前 tmux ls 确认。
  10. 日志文件过大:pipe-pane 是持续追加,配合 logrotate 或定时截断。
  11. send-keys 里的引号:命令含空格/引号时用单引号包住整条,C-m 表示回车。

11. 速查表

tmux new -s name          # 新建
tmux ls                   # 列表
tmux a -t name            # 接入
tmux kill-session -t name # 删除
tmux new -d -s name       # 后台新建
C-b d                     # 分离

# 窗口
C-b c / , / n / p / w / & / 0-9

# 窗格
C-b % / " / 方向键 / o / z / x / !

# 复制
C-b [ / ] ,Space 选择,Enter 复制

# 脚本
tmux send-keys -t s:0.0 'cmd' C-m
tmux capture-pane -t s:0.0 -p -S -500
tmux pipe-pane -t s:0.0 -o 'cat >> /tmp/x.log'