tmux

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

tmux

tmux

Use the
tmux
CLI to interact with running tmux sessions.
使用
tmux
CLI与运行中的tmux会话交互。

Golden Rule: Always Resolve pane_id First

黄金法则:始终优先解析pane_id

Before interacting with any pane, resolve its unique
pane_id
. Use this as the canonical handle for all subsequent operations — it is stable, unambiguous, and survives window/session renames.
bash
undefined
在与任何窗格交互之前,先解析其唯一的
pane_id
,将它作为所有后续操作的规范标识符——它稳定、无歧义,不会受窗口/会话重命名的影响。
bash
undefined

From 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
undefined

List 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
${CLAUDE_SKILL_DIR}/scripts/read-tmux
script — do not use raw
capture-pane
for reading command output.
bash
${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-tmux
脚本读取命令输出,不要直接使用原生
capture-pane
命令。
bash
${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
)

TUI模式(
--tui

Use 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
${CLAUDE_SKILL_DIR}/scripts/read-tmux
and
${CLAUDE_SKILL_DIR}/scripts/send-tmux
auto-decorate panes on first interaction — a yellow "● Operated by Claude" bar appears at the top of the pane. No manual decoration needed.
To 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
在首次交互时会自动给窗格加上装饰——窗格顶部会出现黄色的"● Operated by Claude"栏,无需手动装饰。
使用完窗格后可以移除装饰:
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

Sending Commands

发送命令

Use
send-tmux
— it auto-decorates the pane and passes all arguments to
tmux send-keys
.
bash
undefined
使用
send-tmux
脚本——它会自动给窗格加装饰,并将所有参数传递给
tmux send-keys
命令。
bash
undefined

Run 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
undefined
bash
undefined

List

列出会话

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
undefined
bash
undefined

List

列出窗口

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
undefined
bash
undefined

List (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
undefined
bash
undefined

Pane 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; done
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; done

Open 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" Enter
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" Enter

Interrupt and re-run

中断并重跑命令

bash
tmux send-keys -t %42 C-c
sleep 0.2
tmux send-keys -t %42 "make build" Enter
bash
tmux send-keys -t %42 C-c
sleep 0.2
tmux send-keys -t %42 "make build" Enter