# tmux 里翻不了页 / 看不到上面的输出?(Xshell + tmux 滚动问题) > SSH 连服务器开 tmux 后鼠标滚轮和 PageUp 失效的原因和一劳永逸的配置 ## 问题 通过 Xshell(或其他 SSH 客户端)连到服务器,开了 tmux 之后,鼠标滚轮往上滚、按 PageUp 都没反应,命令输出多了就看不到上面的内容。按 `Ctrl+b` 再按 `[` 想进复制模式,有时也毫无反应,按 `↑` 反而跳出的是历史命令。 ## 原因 tmux 运行在终端的**备用屏幕(alternate screen)**里,自己独立管一套滚动历史(scrollback),不会交给外层终端。所以: - 终端(Xshell)自带的滚动条、滚轮只能看到 tmux 的状态栏那一层,翻不到内容 - 想翻 tmux 自己的历史,必须先按 **prefix 键(默认 `Ctrl+b`)** 进入 copy mode - `Ctrl+b` 有时会被 SSH 客户端截走 —— 于是怎么按都没反应 - tmux 对**单独的 PageUp 没有任何默认绑定**,不进 copy mode 按了也没用 - tmux 默认 `history-limit` 只有 **2000 行**,刷屏多了更早的内容直接被丢掉 `vim` / `less` / `htop` / `top` / `man` 这类全屏程序也用备用屏幕,它们没有历史缓冲,只能用程序自己的翻页键(`less` 里 PageUp/PageDown/`/`搜索/`q`退出)。 ## 解决:配置 ~/.tmux.conf(键盘方案,推荐) 不动鼠标,只让 **PageUp 一按就能往上翻**。在服务器上新建或编辑 `~/.tmux.conf`: ```bash # --- 翻页 / 滚动(纯键盘,不接管鼠标)--- set -g mouse off # 不接管鼠标:右键、拖动选中复制都留给 Xshell set -g history-limit 100000 # 历史缓冲 2000 → 10 万行(仅对之后新开的 pane 生效) set -g mode-keys vi # copy mode 用 vi 键位:k/j 上下,Ctrl-u/Ctrl-d 半屏,g/G 顶底 # 备用 prefix:Ctrl-a(SSH 客户端对它更稳,原来的 Ctrl-b 仍可用) set -g prefix2 C-a bind C-a send-prefix -2 # 单独按 PageUp 就进 copy mode 往上翻一屏;在 vim/less/htop 等全屏程序里则透传给程序 bind -n PageUp if-shell -F "#{alternate_on}" "send-keys PageUp" "copy-mode -eu" bind -n PageDown if-shell -F "#{alternate_on}" "send-keys PageDown" "" # Shift+PageUp/PageDown 同样能用(部分终端会把它截走,所以别只靠它) bind -n S-PageUp copy-mode -eu bind -n S-PageDown send-keys PageDown ``` 热加载(不用重启会话): ```bash tmux source-file ~/.tmux.conf ``` > 注意:不要在有正在运行任务的 tmux 会话里执行 `tmux kill-server`,会把所有会话一起杀掉。用 `source-file` 热加载即可。 ## 之后怎么往上翻 | 场景 | 操作 | |---|---| | 往上翻一屏 | 直接按 **`PageUp`**,`PageDown` 往下,翻到底自动退出 copy mode | | **一次一行** | 进 copy mode 后按 `↑` 或 `k`(下行 `↓` / `j`) | | 半屏 / 整屏 | copy mode 里 `Ctrl-u` / `Ctrl-d` 半屏,`Ctrl-b` / `Ctrl-f` 整屏 | | 跳顶 / 跳底 | copy mode 里 `g` 到最顶,`G` 回到最底 | | 搜索 | copy mode 里 `?` 往上找、`/` 往下找,`n` / `N` 跳下一个 | | 退出 copy mode | `q` 或 `Esc` | | 手动进 copy mode | `Ctrl+a` 然后 `[` | 鼠标保持 `off`,所以右键菜单、「拖动选中即复制」都跟以前一样是 Xshell 在管,不受影响。 ## 如果按了 PageUp 还是没反应 多半是 Xshell 把这个键截走了:查 **工具 → 选项 → 键盘**,看 PageUp 有没有被映射成别的动作;把它改回默认(发送给远端)即可。 ## 附:颜色不对 / 橘色变红?(真彩色透传) 同样是 Xshell + tmux 的坑,但跟滚动无关:在里面跑带彩色 logo / 渐变的程序(比如 Claude Code),本该是**橘黄色**的 logo 显示成**红色**——这是颜色被降级了,不是程序 bug。 **原因**:tmux 默认只向里面的程序宣告 256 色,24-bit 真彩色(truecolor / RGB)不透传。橘色渐变没有精确色位可用,就被就近取整塌成了红色。 在 `~/.tmux.conf` 顶部加 3 行,把「外层 Xshell 支持真彩色」告诉 tmux: ```bash set -g default-terminal "tmux-256color" set -ga terminal-overrides ",xterm:RGB,xterm:colors=256" set -as terminal-features ",xterm*:RGB:256" ``` `tmux source-file ~/.tmux.conf` 热加载后,**新开的窗口 / pane** 里颜色就正常了(已开的旧 pane 不生效)。真彩色对 vim 配色主题、`bat` / `ls` 高亮等也都有好处。 前提是 Xshell 本身开了真彩色:`Alt+P` 会话属性 → **终端 → 颜色** 里勾真彩色 / True Color,断开重连一次。验证: ```bash printf '\033[38;2;217;119;87m● 这个点应该是橘色\033[0m\n' ``` 显示成橘色就对了;显示成红色或灰色说明真彩色还没透传到位。 如果更想用滚轮,把上面的 `set -g mouse off` 改成 `on`,再加两行: ```bash set -g mouse on # copy mode 里滚轮一次滚 3 行(想一次一行就把 -N3 改成 -N1) bind -T copy-mode-vi WheelUpPane send -N3 -X scroll-up bind -T copy-mode-vi WheelDownPane send -N3 -X scroll-down # mouse on 会让 tmux 接管右键并弹出它自己的菜单 —— 这行去掉那个菜单 unbind -n MouseDown3Pane ``` 代价: - **右键**默认会弹 tmux 自己的窗格菜单(上面 `unbind` 那行去掉它) - **拖动选中**选的是 tmux 复制区,不是 Xshell 的;想用 Xshell 原生选中复制要**按住 Shift 再拖** - Xshell 端要额外勾:`Alt+P` 会话属性 → **终端 → VT模式** → 「在备用屏幕缓冲区模式下发送鼠标滚动到应用程序」→ 断开重连一次 ## 万能兜底 不想折腾按键,命令直接接分页器: ```bash 你的命令 2>&1 | less ``` 在 `less` 里 PageUp / PageDown / 空格 / `/`搜索 / `q` 退出,跟 tmux、Xshell 的按键都无关,永远能用。或者存文件:`你的命令 &> ~/out.txt` 再 `less ~/out.txt`。 想临时导出 tmux 当前的历史: ```bash tmux capture-pane -pS -10000 | less # 最近 1 万行 tmux capture-pane -pS - | less # 全部历史 ``` --- **分类**:教程 **标签**:Ctrl · tmux · PageUp **作者**:子龙 **链接**:https://octohz.com/p/2066