Files
Knowledge/1 使用/Linux/tmux 有哪些奇技淫巧?.md
T

266 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[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上手有点门槛,但用熟了真的回不去。现在让我用普通终端开一堆窗口来回切,我会很难受。