tmux
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesetmux
tmux
Use the CLI to interact with running tmux sessions.
tmux使用 CLI与运行中的tmux会话交互。
tmuxGolden Rule: Always Resolve pane_id First
黄金法则:始终优先解析pane_id
Before interacting with any pane, resolve its unique . Use this as the canonical handle for all subsequent operations — it is stable, unambiguous, and survives window/session renames.
pane_idbash
undefined在与任何窗格交互之前,先解析其唯一的,将它作为所有后续操作的规范标识符——它稳定、无歧义,不会受窗口/会话重命名的影响。
pane_idbash
undefinedFrom a user-supplied number (e.g. "pane 1" in the current window)
从用户提供的编号获取(例如当前窗口的"pane 1")
PANE_ID=$(tmux display-message -t :.1 -p '#{pane_id}') # → %42
PANE_ID=$(tmux display-message -t :.1 -p '#{pane_id}') # → %42
From a full target
从完整目标获取
PANE_ID=$(tmux display-message -t 0:2.1 -p '#{pane_id}')
PANE_ID=$(tmux display-message -t 0:2.1 -p '#{pane_id}')
pane_id is valid as a -t target for all pane-level commands
pane_id可以作为所有窗格级别命令的-t参数值
tmux send-keys -t %42 "echo hello" Enter
tmux capture-pane -t %42 -p
tmux select-pane -t %42 -T "my title"
tmux kill-pane -t %42
A pane's `pane_id` changes when it is destroyed and recreated — even at the same index. This means using `pane_id` automatically treats recreated panes as new sessions.
---tmux send-keys -t %42 "echo hello" Enter
tmux capture-pane -t %42 -p
tmux select-pane -t %42 -T "my title"
tmux kill-pane -t %42
当窗格被销毁再重建时,即使位置索引不变,它的`pane_id`也会发生变化,这意味着使用`pane_id`会自动将重建的窗格识别为新会话。
---Resolving Panes by Description
按描述解析窗格
The user may refer to panes informally — "the other pane", "the pane running vim", "the shell on the right". Resolve these yourself before falling back to asking:
bash
undefined用户可能会用非正式的表述指代窗格:"另一个窗格"、"运行vim的窗格"、"右侧的shell",你可以先自行解析,无法确定时再询问用户:
bash
undefinedList all panes in the current window (excluding yourself)
列出当前窗口的所有窗格(排除当前所在窗格)
tmux list-panes -F '#{pane_id} #{pane_current_command}' | grep -v "^$TMUX_PANE "
tmux list-panes -F '#{pane_id} #{pane_current_command}' | grep -v "^$TMUX_PANE "
"The other pane" / "the only other pane" — works when there are exactly 2 panes
当窗口恰好有2个窗格时,可以用该命令获取"另一个窗格"/"唯一的其他窗格"
PANE_ID=$(tmux list-panes -F '#{pane_id}' | grep -v "^$TMUX_PANE$")
PANE_ID=$(tmux list-panes -F '#{pane_id}' | grep -v "^$TMUX_PANE$")
"The pane running vim"
获取"运行vim的窗格"
PANE_ID=$(tmux list-panes -F '#{pane_id} #{pane_current_command}' | grep vim | awk '{print $1}')
Use `$TMUX_PANE` (your own pane ID, set automatically by tmux) to exclude yourself from the list.
If the description is ambiguous or matches multiple panes, ask the user:
1. Run `tmux display-panes -d 5000` — numbered overlays appear for 5 seconds
2. Ask the user which number
3. Resolve with `:.N`:
```bash
PANE_ID=$(tmux display-message -t :.1 -p '#{pane_id}')PANE_ID=$(tmux list-panes -F '#{pane_id} #{pane_current_command}' | grep vim | awk '{print $1}')
使用tmux自动设置的当前窗格ID变量`$TMUX_PANE`可以将自身从列表中排除。
如果描述有歧义或者匹配到多个窗格,按以下步骤询问用户:
1. 执行`tmux display-panes -d 5000`——窗格上会显示5秒的编号覆盖层
2. 询问用户对应的编号
3. 使用`:.N`格式解析pane_id:
```bash
PANE_ID=$(tmux display-message -t :.1 -p '#{pane_id}')Reading Pane Output
读取窗格输出
Use the script — do not use raw for reading command output.
${CLAUDE_SKILL_DIR}/scripts/read-tmuxcapture-panebash
${CLAUDE_SKILL_DIR}/scripts/read-tmux %42 # delta mode (default) — for shell output
${CLAUDE_SKILL_DIR}/scripts/read-tmux --tui %42 # TUI mode — diff of changed screen regions
${CLAUDE_SKILL_DIR}/scripts/read-tmux --full %42 # TUI mode — always full screen (no diff)使用脚本读取命令输出,不要直接使用原生命令。
${CLAUDE_SKILL_DIR}/scripts/read-tmuxcapture-panebash
${CLAUDE_SKILL_DIR}/scripts/read-tmux %42 # 增量模式(默认)——适用于shell输出
${CLAUDE_SKILL_DIR}/scripts/read-tmux --tui %42 # TUI模式——对比屏幕变化区域的差异
${CLAUDE_SKILL_DIR}/scripts/read-tmux --full %42 # TUI模式——始终返回全屏内容(无差异对比)Delta mode (default)
增量模式(默认)
- First call: captures full scrollback, saves position marker, prints ≤4KB
- Subsequent calls: captures only new lines since last read
- No changes: prints
(no new output)
- 首次调用:捕获完整的滚动历史,保存位置标记,最多返回4KB内容
- 后续调用:仅捕获上次读取之后新增的行
- 无变化时:输出
(no new output)
TUI mode (--tui
)
--tuiTUI模式(--tui
)
--tuiUse for any full-screen application (vim, htop, lazygit, top, etc.).
- First call: captures full visible screen, saves snapshot
- Subsequent calls: diffs against previous capture
- If ≤50% of lines changed → shows unified diff (only changed regions)
- If >50% of lines changed → shows full screen (heavy redraw fallback)
- No changes: prints
(no changes on screen)
适用于所有全屏应用(vim、htop、lazygit、top等)。
- 首次调用:捕获完整的可见屏幕内容,保存快照
- 后续调用:与上次捕获的内容做差异对比
- 如果改动行数≤50% → 展示统一差异格式(仅显示改动区域)
- 如果改动行数>50% → 展示全屏内容(重绘量大时的降级方案)
- 无变化时:输出
(no changes on screen)
Output capping
输出截断
All output is capped at first 2000 + last 2000 bytes; middle is truncated if exceeded.
所有输出最多保留前2000字节+后2000字节,超出部分的中间内容会被截断。
State directory
状态目录
State is stored in :
/tmp/tmux-skill/<pane_id>/position ← line counter for delta mode
tui_prev ← last TUI capture for diffing状态存储在目录下:
/tmp/tmux-skill/<pane_id>/position ← 增量模式的行计数器
tui_prev ← 用于差异对比的上一次TUI捕获内容Pane Decoration
窗格装饰
Both and auto-decorate panes on first interaction — a yellow "● Operated by Claude" bar appears at the top of the pane. No manual decoration needed.
${CLAUDE_SKILL_DIR}/scripts/read-tmux${CLAUDE_SKILL_DIR}/scripts/send-tmuxTo release decoration when done with a pane:
bash
tmux set-option -p -t %42 -u pane-border-status 2>/dev/null || true
tmux set-option -p -t %42 -u pane-border-format 2>/dev/null || true${CLAUDE_SKILL_DIR}/scripts/read-tmux${CLAUDE_SKILL_DIR}/scripts/send-tmux使用完窗格后可以移除装饰:
bash
tmux set-option -p -t %42 -u pane-border-status 2>/dev/null || true
tmux set-option -p -t %42 -u pane-border-format 2>/dev/null || trueSending Commands
发送命令
Use — it auto-decorates the pane and passes all arguments to .
send-tmuxtmux send-keysbash
undefined使用脚本——它会自动给窗格加装饰,并将所有参数传递给命令。
send-tmuxtmux send-keysbash
undefinedRun a command
运行命令
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 "npm test" Enter
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 "npm test" Enter
Interrupt
中断命令
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 C-c
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 C-c
Send EOF / exit shell
发送EOF/退出shell
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 C-d
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 C-d
Quit a pager
退出分页器
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 q
---${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 q
---Sessions
会话
bash
undefinedbash
undefinedList
列出会话
tmux list-sessions
tmux list-sessions -F '#{session_name} (#{session_windows} windows)'
tmux list-sessions
tmux list-sessions -F '#{session_name} (#{session_windows} windows)'
Create (detached)
创建后台会话
tmux new-session -d -s <name> [-c <start-dir>]
tmux new-session -d -s <name> [-c <start-dir>]
Rename
重命名会话
tmux rename-session -t <old> <new>
tmux rename-session -t <old> <new>
Kill
销毁会话
tmux kill-session -t <name>
tmux kill-session -t <name>
Check existence
检查会话是否存在
tmux has-session -t <name> 2>/dev/null && echo exists
---tmux has-session -t <name> 2>/dev/null && echo exists
---Windows
窗口
bash
undefinedbash
undefinedList
列出窗口
tmux list-windows -t <session>
tmux list-windows -t <session> -F '#{window_index}: #{window_name}'
tmux list-windows -t <session>
tmux list-windows -t <session> -F '#{window_index}: #{window_name}'
Create
创建窗口
tmux new-window -t <session> -n <name> [-c <dir>]
tmux new-window -t <session> -n <name> [-c <dir>]
Rename
重命名窗口
tmux rename-window -t <session>:<index> <new-name>
tmux rename-window -t <session>:<index> <new-name>
Move to another session or index
移动窗口到其他会话或位置
tmux move-window -s <session>:<index> -t <dst-session>:<new-index>
tmux move-window -s <session>:<index> -t <dst-session>:<new-index>
Swap two windows
交换两个窗口位置
tmux swap-window -s <session>:<a> -t <session>:<b>
tmux swap-window -s <session>:<a> -t <session>:<b>
Kill
销毁窗口
tmux kill-window -t <session>:<index>
---tmux kill-window -t <session>:<index>
---Panes
窗格
bash
undefinedbash
undefinedList (resolve pane_id for any pane you'll interact with)
列出窗格(后续要交互的窗格都要先解析pane_id)
tmux list-panes -t <session>:<window> -F '#{pane_index} #{pane_id} #{pane_current_command}'
tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_id} #{pane_current_command}'
tmux list-panes -t <session>:<window> -F '#{pane_index} #{pane_id} #{pane_current_command}'
tmux list-panes -a -F '#{session_name}:#{window_index}.#{pane_index} #{pane_id} #{pane_current_command}'
Create — split relative to Claude's own pane so it opens in the right window.
创建窗格——相对Claude所在的窗格拆分,确保在正确的窗口打开
$TMUX_PANE is Claude's pane_id, set automatically by tmux.
$TMUX_PANE是Claude所在的窗格ID,由tmux自动设置
-P -F prints the new pane's id directly.
-P -F参数会直接输出新窗格的id
PANE_ID=$(tmux split-window -h -t "$TMUX_PANE" -P -F '#{pane_id}') # side by side
PANE_ID=$(tmux split-window -v -t "$TMUX_PANE" -P -F '#{pane_id}') # top/bottom
PANE_ID=$(tmux split-window -h -t "$TMUX_PANE" -P -F '#{pane_id}') # 左右分屏
PANE_ID=$(tmux split-window -v -t "$TMUX_PANE" -P -F '#{pane_id}') # 上下分屏
Rename (sets title shown in pane border)
重命名窗格(设置窗格边框显示的标题)
tmux select-pane -t %42 -T <title>
tmux select-pane -t %42 -T <title>
Move pane to another window
移动窗格到其他窗口
tmux move-pane -s %42 -t <dst-session>:<dst-window>
tmux move-pane -s %42 -t <dst-session>:<dst-window>
Break pane out into its own window
将窗格拆分出来作为独立窗口
tmux break-pane -t %42 -n <new-window-name>
tmux break-pane -t %42 -n <new-window-name>
Join a window into another as a pane
将窗口作为窗格合并到另一个窗口
tmux join-pane -s <src-window> -t <dst-window>
tmux join-pane -s <src-window> -t <dst-window>
Swap two panes
交换两个窗格位置
tmux swap-pane -s %42 -t %99
tmux swap-pane -s %42 -t %99
Kill
销毁窗格
tmux kill-pane -t %42
---tmux kill-pane -t %42
---Querying State
状态查询
bash
undefinedbash
undefinedPane properties
窗格属性查询
tmux display-message -t %42 -p '#{pane_id}'
tmux display-message -t %42 -p '#{pane_current_command}'
tmux display-message -t %42 -p '#{pane_current_path}'
tmux display-message -t %42 -p '#{pane_pid}'
tmux display-message -t %42 -p '#{pane_id}'
tmux display-message -t %42 -p '#{pane_current_command}'
tmux display-message -t %42 -p '#{pane_current_path}'
tmux display-message -t %42 -p '#{pane_pid}'
Useful format variables
常用格式变量
#{pane_id} unique pane identifier (%42)
#{pane_id} 唯一的窗格标识符(格式如%42)
#{pane_index} position within window (can be reused after kill)
#{pane_index} 窗格在窗口内的位置索引(销毁后可被复用)
#{pane_current_command} process running in pane
#{pane_current_command} 窗格内运行的进程
#{pane_current_path} working directory
#{pane_current_path} 工作目录
#{pane_pid} PID of pane shell
#{pane_pid} 窗格shell的PID
#{session_name} session name
#{session_name} 会话名称
#{window_index} window number
#{window_index} 窗口编号
#{window_name} window name
#{window_name} 窗口名称
---
---Practical Patterns
实用模式
Poll until a command finishes
轮询直到命令执行完成
bash
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 "make build && echo __DONE__" Enter
while ! ${CLAUDE_SKILL_DIR}/scripts/read-tmux %42 | grep -q "__DONE__"; do sleep 0.5; donebash
${CLAUDE_SKILL_DIR}/scripts/send-tmux %42 "make build && echo __DONE__" Enter
while ! ${CLAUDE_SKILL_DIR}/scripts/read-tmux %42 | grep -q "__DONE__"; do sleep 0.5; doneOpen a new pane for a project task
为项目任务打开新窗格
bash
WINDOW=$(tmux new-window -t myproject -n build -P -F '#{window_index}')
PANE_ID=$(tmux display-message -t "myproject:${WINDOW}.0" -p '#{pane_id}')
tmux select-pane -t "$PANE_ID" -T "● claude"
tmux send-keys -t "$PANE_ID" "make build" Enterbash
WINDOW=$(tmux new-window -t myproject -n build -P -F '#{window_index}')
PANE_ID=$(tmux display-message -t "myproject:${WINDOW}.0" -p '#{pane_id}')
tmux select-pane -t "$PANE_ID" -T "● claude"
tmux send-keys -t "$PANE_ID" "make build" EnterInterrupt and re-run
中断并重跑命令
bash
tmux send-keys -t %42 C-c
sleep 0.2
tmux send-keys -t %42 "make build" Enterbash
tmux send-keys -t %42 C-c
sleep 0.2
tmux send-keys -t %42 "make build" Enter