tmux
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesetmux Skill
tmux 技能指南
Use tmux as a programmable terminal multiplexer for interactive work. Works on Linux and macOS with stock tmux; avoid custom config by using a private socket.
将tmux用作可编程的终端复用器,以进行交互式操作。可在Linux和macOS系统上配合原生tmux使用;通过使用私有套接字来避免自定义配置的干扰。
Quickstart (isolated socket)
快速开始(使用独立套接字)
bash
SOCKET_DIR=${TMPDIR:-/tmp}/claude-tmux-sockets # well-known dir for all agent sockets
mkdir -p "$SOCKET_DIR"
SOCKET="$SOCKET_DIR/claude.sock" # keep agent sessions separate from your personal tmux
SESSION=claude-python # slug-like names; avoid spaces
tmux -S "$SOCKET" new -d -s "$SESSION" -n shell
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- 'python3 -q' Enter
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200 # watch output
tmux -S "$SOCKET" kill-session -t "$SESSION" # clean upAfter starting a session ALWAYS tell the user how to monitor the session by giving them a command to copy paste:
To monitor this session yourself:
tmux -S "$SOCKET" attach -t claude-lldb
Or to capture the output once:
tmux -S "$SOCKET" capture-pane -p -J -t claude-lldb:0.0 -S -200This must ALWAYS be printed right after a session was started and once again at the end of the tool loop. But the earlier you send it, the happier the user will be.
bash
SOCKET_DIR=${TMPDIR:-/tmp}/claude-tmux-sockets # 所有Agent套接字的通用目录
mkdir -p "$SOCKET_DIR"
SOCKET="$SOCKET_DIR/claude.sock" # 将Agent会话与个人tmux会话分开
SESSION=claude-python # 使用类似短别名的名称;避免空格
tmux -S "$SOCKET" new -d -s "$SESSION" -n shell
tmux -S "$SOCKET" send-keys -t "$SESSION":0.0 -- 'python3 -q' Enter
tmux -S "$SOCKET" capture-pane -p -J -t "$SESSION":0.0 -S -200 # 查看输出
tmux -S "$SOCKET" kill-session -t "$SESSION" # 清理会话启动会话后,务必为用户提供可直接复制粘贴的监控命令,告知其如何监控会话:
要自行监控此会话:
tmux -S "$SOCKET" attach -t claude-lldb
或者一次性捕获输出:
tmux -S "$SOCKET" capture-pane -p -J -t claude-lldb:0.0 -S -200这段内容必须在会话启动后立即打印,并且在工具循环结束时再次打印。越早提供该命令,用户体验越好。
Socket convention
套接字约定
- Agents MUST place tmux sockets under (defaults to
CLAUDE_TMUX_SOCKET_DIR) and use${TMPDIR:-/tmp}/claude-tmux-socketsso we can enumerate/clean them. Create the dir first:tmux -S "$SOCKET".mkdir -p "$CLAUDE_TMUX_SOCKET_DIR" - Default socket path to use unless you must isolate further: .
SOCKET="$CLAUDE_TMUX_SOCKET_DIR/claude.sock"
- Agent必须将tmux套接字放置在目录下(默认路径为
CLAUDE_TMUX_SOCKET_DIR),并使用${TMPDIR:-/tmp}/claude-tmux-sockets命令,以便我们可以枚举和清理这些套接字。请先创建该目录:tmux -S "$SOCKET"。mkdir -p "$CLAUDE_TMUX_SOCKET_DIR" - 除非需要进一步隔离,否则默认使用以下套接字路径:。
SOCKET="$CLAUDE_TMUX_SOCKET_DIR/claude.sock"
Targeting panes and naming
面板定位与命名规则
- Target format: , defaults to
{session}:{window}.{pane}if omitted. Keep names short (e.g.,:0.0,claude-py).claude-gdb - Use consistently to stay on the private socket path. If you need user config, drop
-S "$SOCKET"; otherwise-f /dev/nullgives a clean config.-f /dev/null - Inspect: ,
tmux -S "$SOCKET" list-sessions.tmux -S "$SOCKET" list-panes -a
- 目标格式:,如果省略则默认使用
{session}:{window}.{pane}。请使用简短名称(如:0.0、claude-py)。claude-gdb - 始终坚持使用参数以确保使用私有套接字路径。如果需要使用用户配置,请去掉
-S "$SOCKET";否则,-f /dev/null会提供一个干净的配置环境。-f /dev/null - 查看会话信息:、
tmux -S "$SOCKET" list-sessions。tmux -S "$SOCKET" list-panes -a
Finding sessions
查找会话
- List sessions on your active socket with metadata: ; add
./scripts/find-sessions.sh -S "$SOCKET"to filter.-q partial-name - Scan all sockets under the shared directory: (uses
./scripts/find-sessions.sh --allorCLAUDE_TMUX_SOCKET_DIR).${TMPDIR:-/tmp}/claude-tmux-sockets
- 使用以下命令列出当前活动套接字上的会话及元数据:;添加
./scripts/find-sessions.sh -S "$SOCKET"参数可进行模糊过滤。-q partial-name - 扫描共享目录下的所有套接字:(使用
./scripts/find-sessions.sh --all或默认路径CLAUDE_TMUX_SOCKET_DIR)。${TMPDIR:-/tmp}/claude-tmux-sockets
Sending input safely
安全发送输入
- Prefer literal sends to avoid shell splitting:
tmux -L "$SOCKET" send-keys -t target -l -- "$cmd" - When composing inline commands, use single quotes or ANSI C quoting to avoid expansion: .
tmux ... send-keys -t target -- $'python3 -m http.server 8000' - To send control keys: ,
tmux ... send-keys -t target C-c,C-d,C-z, etc.Escape
- 优先使用字面量发送方式以避免Shell拆分:
tmux -L "$SOCKET" send-keys -t target -l -- "$cmd" - 当编写内联命令时,使用单引号或ANSI C引号来避免展开:。
tmux ... send-keys -t target -- $'python3 -m http.server 8000' - 发送控制键的方式:、
tmux ... send-keys -t target C-c、C-d、C-z等。Escape
Watching output
监控输出
- Capture recent history (joined lines to avoid wrapping artifacts): .
tmux -L "$SOCKET" capture-pane -p -J -t target -S -200 - For continuous monitoring, poll with the helper script (below) instead of (which does not watch pane output).
tmux wait-for - You can also temporarily attach to observe: ; detach with
tmux -L "$SOCKET" attach -t "$SESSION".Ctrl+b d - When giving instructions to a user, explicitly print a copy/paste monitor command alongside the action don't assume they remembered the command.
- 捕获近期历史记录(合并行以避免换行异常):。
tmux -L "$SOCKET" capture-pane -p -J -t target -S -200 - 如需持续监控,请使用辅助脚本(如下)进行轮询,而非(该命令无法监控面板输出)。
tmux wait-for - 你也可以临时附加到会话进行观察:;使用
tmux -L "$SOCKET" attach -t "$SESSION"进行分离。Ctrl+b d - 当向用户提供操作说明时,务必在操作步骤旁明确打印可复制粘贴的监控命令,不要假设用户记得该命令。
Spawning Processes
启动进程
Some special rules for processes:
- when asked to debug, use lldb by default
- when starting a python interactive shell, always set the environment variable. This is very important as the non-basic console interferes with your send-keys.
PYTHON_BASIC_REPL=1
关于启动进程的特殊规则:
- 当需要调试时,默认使用lldb
- 启动Python交互式Shell时,始终设置环境变量。这一点非常重要,因为非基础控制台会干扰按键指令的发送。
PYTHON_BASIC_REPL=1
Synchronizing / waiting for prompts
同步/等待提示符
- Use timed polling to avoid races with interactive tools. Example: wait for a Python prompt before sending code:
bash
./scripts/wait-for-text.sh -t "$SESSION":0.0 -p '^>>>' -T 15 -l 4000 - For long-running commands, poll for completion text (,
"Type quit to exit", etc.) before proceeding."Program exited"
- 使用定时轮询来避免与交互式工具的竞争条件。示例:在发送代码前等待Python提示符出现:
bash
./scripts/wait-for-text.sh -t "$SESSION":0.0 -p '^>>>' -T 15 -l 4000 - 对于长时间运行的命令,在继续操作前轮询完成标识文本(如、
"Type quit to exit"等)。"Program exited"
Interactive tool recipes
交互式工具使用示例
- Python REPL: ; wait for
tmux ... send-keys -- 'python3 -q' Enter; send code with^>>>; interrupt with-l. Always withC-c.PYTHON_BASIC_REPL - gdb: ; disable paging
tmux ... send-keys -- 'gdb --quiet ./a.out' Enter; break withtmux ... send-keys -- 'set pagination off' Enter; issueC-c,bt, etc.; exit viainfo localsthen confirmquit.y - Other TTY apps (ipdb, psql, mysql, node, bash): same pattern—start the program, poll for its prompt, then send literal text and Enter.
- Python REPL:;等待
tmux ... send-keys -- 'python3 -q' Enter提示符;使用^>>>参数发送代码;使用-l中断。务必设置C-c环境变量。PYTHON_BASIC_REPL - gdb:;禁用分页功能
tmux ... send-keys -- 'gdb --quiet ./a.out' Enter;使用tmux ... send-keys -- 'set pagination off' Enter中断;执行C-c、bt等命令;通过info locals命令退出,然后输入quit确认。y - 其他TTY应用(ipdb、psql、mysql、node、bash):遵循相同模式——启动程序,轮询其提示符,然后发送字面量文本并按Enter。
Cleanup
清理会话
- Kill a session when done: .
tmux -S "$SOCKET" kill-session -t "$SESSION" - Kill all sessions on a socket: .
tmux -S "$SOCKET" list-sessions -F '#{session_name}' | xargs -r -n1 tmux -S "$SOCKET" kill-session -t - Remove everything on the private socket: .
tmux -S "$SOCKET" kill-server
- 完成操作后终止会话:。
tmux -S "$SOCKET" kill-session -t "$SESSION" - 终止某个套接字上的所有会话:。
tmux -S "$SOCKET" list-sessions -F '#{session_name}' | xargs -r -n1 tmux -S "$SOCKET" kill-session -t - 清除私有套接字上的所有内容:。
tmux -S "$SOCKET" kill-server
Helper: wait-for-text.sh
辅助脚本:wait-for-text.sh
./scripts/wait-for-text.shbash
./scripts/wait-for-text.sh -t session:0.0 -p 'pattern' [-F] [-T 20] [-i 0.5] [-l 2000]- /
-tpane target (required)--target - /
-pregex to match (required); add--patternfor fixed string-F - timeout seconds (integer, default 15)
-T - poll interval seconds (default 0.5)
-i - history lines to search from the pane (integer, default 1000)
-l - Exits 0 on first match, 1 on timeout. On failure prints the last captured text to stderr to aid debugging.
./scripts/wait-for-text.shbash
./scripts/wait-for-text.sh -t session:0.0 -p 'pattern' [-F] [-T 20] [-i 0.5] [-l 2000]- /
-t面板目标(必填)--target - /
-p要匹配的正则表达式(必填);添加--pattern参数可匹配固定字符串-F - 超时时间(秒,整数,默认15)
-T - 轮询间隔(秒,默认0.5)
-i - 要搜索的面板历史行数(整数,默认1000)
-l - 匹配成功时退出码为0,超时则为1。失败时会将最后捕获的文本打印到标准错误流,以帮助调试。