[SSH](https://zhida.zhihu.com/search?content_id=763139071&content_type=Answer&match_order=1&q=SSH&zhida_source=entity)连服务器跑脚本,网一断任务就没了,这事吃过几次亏之后我开始用[tmux](https://zhida.zhihu.com/search?content_id=763139071&content_type=Answer&match_order=1&q=tmux&zhida_source=entity)。后来发现这东西不止能防断网,还有不少骚操作。 --- **1. 断网保命** SSH连服务器跑个脚本,网一抖任务就没了。 tmux解决这个问题: ```text tmux new -s deploy ./deploy.sh # Ctrl+b d 断开 ``` 任务在服务器上跑着,你断开连接、关电脑、换个地方都行。回来 `tmux a -t deploy` 继续看。 我有次在高铁上部署,信号断断续续,靠这个救了。不然那个迁移脚本跑一半断了,数据库就成半成品了。 --- **2. 一屏多用** ```text Ctrl+b % # 左右分屏 Ctrl+b " # 上下分屏 Ctrl+b 方向键 # 切换 ``` 我日常开发的布局: ```text ┌─────────────────┬─────────────────┐ │ │ tail -f log │ │ vim/code ├─────────────────┤ │ │ shell │ └─────────────────┴─────────────────┘ ``` 左边写代码,右上角看日志,右下角跑命令。一个终端三件事。 `Ctrl+b z` 可以把当前面板最大化,再按一次恢复。看日志的时候放大看,看完缩回去,不用来回开终端。 --- **3. 会话不是一次性的** 很多人把tmux当成”防断网工具”,用完就kill。 其实可以给不同项目建不同会话: ```text tmux new -s project-a tmux new -s project-b tmux new -s server-monitor ``` 每个会话保持自己的布局、目录、运行的命令。 `Ctrl+b s` 可以在会话之间切换,像切换桌面一样。早上来了 `tmux a -t project-a`,下班 `Ctrl+b d`,第二天接着搞。 --- **4. 改掉反人类的默认配置** tmux默认的 `Ctrl+b` 太难按了,b键离得太远。 改成 `Ctrl+a`: ```text # ~/.tmux.conf unbind C-b set -g prefix C-a bind C-a send-prefix ``` 分屏的 `%` 和 `"` 也反直觉,改成 `|` 和 `-`: ```text bind | split-window -h -c "#{pane_current_path}" bind - split-window -v -c "#{pane_current_path}" ``` `-c "#{pane_current_path}"` 是让新分出来的面板保持当前目录,不然每次都从~开始,还得cd。 鼠标支持默认是关的,开了之后可以点击切换面板、拖拽调整大小、滚轮看历史: ```text set -g mouse on ``` 改完后 `tmux source-file ~/.tmux.conf` 生效。 --- **5. vim键位移动** 如果你用vim,在tmux里也用vim键位会很爽: ```text # ~/.tmux.conf bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R ``` 这样 `Ctrl+a h/j/k/l` 就能上下左右切换面板,不用去够方向键。 复制模式也改成vi键位: ```text setw -g mode-keys vi ``` `Ctrl+a [` 进入复制模式后,用 j/k 上下移动,`/` 搜索,空格开始选择,回车复制。 --- **6. 同步输入** 这个很少有人知道: ```text Ctrl+a :setw synchronize-panes on ``` 开了之后,你在一个面板敲的东西会同时出现在所有面板。 用途:同时操作多台服务器。 ```text # 开四个面板,分别ssh到四台服务器 # 然后开启同步输入 # 敲一遍命令,四台服务器同时执行 ``` 批量重启服务、批量改配置,效率翻几倍。 再敲一遍 `setw synchronize-panes off` 关掉。 --- **7. 发送命令到其他面板** 有时候想在脚本里控制tmux,比如自动化开发环境启动: ```text #!/bin/bash tmux new-session -d -s dev # 第一个面板跑后端 tmux send-keys -t dev 'cd ~/project/backend && npm run dev' Enter # 分屏,第二个面板跑前端 tmux split-window -h -t dev tmux send-keys -t dev 'cd ~/project/frontend && npm run dev' Enter # 再分屏,第三个面板开着备用 tmux split-window -v -t dev tmux attach -t dev ``` 每天跑一下这个脚本,开发环境就全起来了,不用手动一个个开。 --- **8. 会话持久化** tmux的会话在服务器重启后会没。 装 [tmux-resurrect](https://zhida.zhihu.com/search?content_id=763139071&content_type=Answer&match_order=1&q=tmux-resurrect&zhida_source=entity) 插件可以保存和恢复: ```text # 装插件管理器 git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm # ~/.tmux.conf 加上 set -g @plugin 'tmux-plugins/tpm' set -g @plugin 'tmux-plugins/tmux-resurrect' run '~/.tmux/plugins/tpm/tpm' ``` 重载配置,`Ctrl+a I` 安装插件。 之后 `Ctrl+a Ctrl+s` 保存会话,`Ctrl+a Ctrl+r` 恢复。服务器重启了也能恢复到之前的布局。 --- **9. 共享终端** 两个人可以同时连同一个会话: ```text # A创建 tmux new -s pair # B连接 tmux a -t pair ``` 两个人看到的完全同步,A敲的B能看到,B敲的A也能看到。 远程带人排查问题、[pair programming](https://zhida.zhihu.com/search?content_id=763139071&content_type=Answer&match_order=1&q=pair+programming&zhida_source=entity)都能用。比共享屏幕流畅,因为只传文字不传画面。 我带新人排查线上问题就用这个,他在他电脑上操作,我实时看着,随时能接手。如果服务器在内网连不上的话,可以用星空组网之类的工具先把网络打通,然后再共享tmux会话。 --- **10. 快速切窗口** 窗口多了之后,`Ctrl+a n/p` 一个个切太慢。 `Ctrl+a w` 可以列出所有窗口,上下选择,回车切换。还能预览每个窗口里在跑什么。 或者直接 `Ctrl+a 数字` 切到对应窗口。但默认窗口编号从0开始,改成从1开始更顺手: ```text set -g base-index 1 setw -g pane-base-index 1 ``` --- 最后贴一下我的完整配置,直接抄就能用: ```text # ~/.tmux.conf # 前缀改成Ctrl+a unbind C-b set -g prefix C-a bind C-a send-prefix # 鼠标 set -g mouse on # 历史 set -g history-limit 50000 # 窗口编号从1开始 set -g base-index 1 setw -g pane-base-index 1 set -g renumber-windows on # 分屏 bind | split-window -h -c "#{pane_current_path}" bind - split-window -v -c "#{pane_current_path}" # vim式移动 bind h select-pane -L bind j select-pane -D bind k select-pane -U bind l select-pane -R setw -g mode-keys vi # 减少延迟 set -sg escape-time 0 # 快速重载 bind r source-file ~/.tmux.conf \; display "Reloaded" ``` tmux上手有点门槛,但用熟了真的回不去。现在让我用普通终端开一堆窗口来回切,我会很难受。