Tmux 实践

七月 18, 2025 [tools] #tmux #clipboard #ssh #terminal

Tmux 实践

剪贴板集成

方案一:OSC 52 转义序列

OSC 52 让 tmux 通过终端转义序列直接设置系统剪贴板。优点:SSH 远程会话也能用,无需 X11 转发。

三步配置

1. 确认 set-clipboard 已启用

tmux show -s set-clipboard  # 应为 on 或 external

.tmux.conf 中:

set -s set-clipboard external  # tmux >= 2.6

external 只允许 tmux 自身设置剪贴板,内部应用不能。

2. 确认 Ms capability 存在

tmux info | grep Ms:  # 应有 (string) \033]52;...

如果是 [missing],在 .tmux.conf 中添加(tmux >= 3.2):

set -as terminal-features ',rxvt-unicode-256color:clipboard'

旧版 tmux:

set -as terminal-overrides ',rxvt-unicode-256color:Ms=\E]52;%p1%s;%p2%s\007'

3. 终端侧启用 OSC 52

tmux 嵌套:外层 tmux 需 set-clipboard on

方案二:外部工具(xclip/xsel)

配置 copy-command(tmux >= 3.2):

set -s copy-command 'xsel -i'

或修改复制键绑定(旧版):

bind -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "xsel -i --clipboard"

注意:xclip 有 stdout 不关闭的 bug,需 xclip >/dev/null

X 有多个剪贴板:primary(中键粘贴)、clipboard(Ctrl+V)。用 xclip -selectionxsel --clipboard 选择。

滚动缓冲区

tmux 运行在终端的 alternate screen buffer,自身维护 scrollback buffer。进入 copy mode 才能浏览历史。

推荐配置

# Alt+Up 进入 copy mode
bind -n M-Up copy-mode

# 在 copy mode 中滚动
bind -T copy-mode-vi M-Up              send-keys -X scroll-up
bind -T copy-mode-vi M-Down            send-keys -X scroll-down
bind -T copy-mode-vi M-PageUp          send-keys -X halfpage-up
bind -T copy-mode-vi M-PageDown        send-keys -X halfpage-down
bind -T copy-mode-vi PageDown          send-keys -X page-down
bind -T copy-mode-vi PageUp            send-keys -X page-up

# 鼠标滚轮调整为每次滚 2 行(默认 5)
bind -T copy-mode-vi WheelUpPane select-pane \; send-keys -X -N 2 scroll-up
bind -T copy-mode-vi WheelDownPane select-pane \; send-keys -X -N 2 scroll-down

set -g mouse on

粘贴

bind p paste-buffer
bind C-p choose-buffer

嵌套 tmux 会话

通过 F12 切换 key table,让内层 tmux 不受外层干扰:

bind -T root F12 \
  set prefix None \;\
  set key-table off \;\
  refresh-client -S \;\

bind -T off F12 \
  set -u prefix \;\
  set -u key-table \;\
  refresh-client -S

自动检测远程会话:

if-shell 'test -n "$SSH_CLIENT"' 'source-file ~/.tmux/tmux.remote.conf'

远程 SSH 会话复制文本

方法:SSH 远程隧道 + systemd socket 服务

1. 创建 xclip socket 服务/etc/systemd/system/xclip.socket):

[Unit]
Description=Network copy backend for tmux based on xclip

[Socket]
ListenStream=19988
Accept=yes

[Install]
WantedBy=sockets.target

2. 创建对应服务/etc/systemd/system/xclip@.service):

[Unit]
Description=Copy backend service piping input to xclip

[Service]
Type=simple
ExecStart=/usr/bin/xclip -i -f -selection primary | /usr/bin/xclip -i -selection clipboard
StandardInput=socket
StandardOutput=socket
sudo systemctl enable xclip.socket && sudo systemctl start xclip.socket

3. SSH 远程端口转发

ssh -R 19988:localhost:19988 user@remote

或写入 ~/.ssh/config

Host remote
  RemoteForward 19988 localhost:19988

4. tmux 中自动选择后端yank.sh):

优先 xsel / xclip,失败则检测 19988 端口是否有监听:

elif [ "$(ss -n -4 state listening '( sport = 19988 )' | tail -n +2 | wc -l)" -eq 1 ]; then
  copy_backend="nc localhost 19988"
fi

限制:同一远程机器上多个 SSH 会话共用同一端口只有第一个能正常复制,需分配不同端口。