tmux

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

tmux Process Management

tmux 进程管理

Session Reuse Rules

会话复用规则

These are hard requirements, not suggestions:
  • MUST check
    tmux has-session
    before ever calling
    tmux new-session
  • MUST derive session name from
    git rev-parse --show-toplevel
    , never hardcode
  • MUST add windows to an existing project session, never create a parallel session
  • MUST use
    send-keys
    to run commands, never pass inline commands to
    new-session
  • NEVER create a new session if one already exists for the current project
One project = one tmux session. Multiple processes = multiple windows within that session.
这些是硬性要求,而非建议:
  • 必须在调用
    tmux new-session
    之前检查
    tmux has-session
  • 必须
    git rev-parse --show-toplevel
    生成会话名称,绝对不能硬编码
  • 必须向现有项目会话中添加窗口,绝不能创建并行会话
  • 必须使用
    send-keys
    来运行命令,绝不能向
    new-session
    传递内联命令
  • 绝不能在当前项目已有会话的情况下创建新会话
一个项目对应一个tmux会话。多个进程对应该会话中的多个窗口。

Interactive Shell Requirement

交互式Shell要求

Use send-keys pattern for reliable shell initialization. Creating a session spawns an interactive shell automatically. Use
send-keys
to run commands within that shell, ensuring PATH, direnv, and other initialization runs properly.
bash
undefined
使用send-keys模式确保Shell初始化可靠。 创建会话时会自动生成交互式Shell。使用
send-keys
在该Shell中运行命令,确保PATH、direnv和其他初始化操作正常执行。
bash
undefined

WRONG - inline command bypasses shell init, breaks PATH/direnv

错误示例 - 内联命令会跳过Shell初始化,破坏PATH/direnv

tmux new-session -d -s "$SESSION" -n main 'tilt up'
tmux new-session -d -s "$SESSION" -n main 'tilt up'

CORRECT - check for session, then use send-keys in interactive shell

正确示例 - 检查会话,然后在交互式Shell中使用send-keys

if ! tmux has-session -t "$SESSION" 2>/dev/null; then tmux new-session -d -s "$SESSION" -n main fi tmux send-keys -t "$SESSION:main" 'tilt up' Enter
undefined
if ! tmux has-session -t "$SESSION" 2>/dev/null; then tmux new-session -d -s "$SESSION" -n main fi tmux send-keys -t "$SESSION:main" 'tilt up' Enter
undefined

Session Naming Convention

会话命名规范

Always derive session name from the project:
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
For multiple processes in one project, use windows not separate sessions:
  • Session:
    myapp
  • Windows:
    server
    ,
    tests
    ,
    logs
始终从项目中生成会话名称:
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
对于单个项目中的多个进程,使用窗口而非独立会话:
  • 会话:
    myapp
  • 窗口:
    server
    ,
    tests
    ,
    logs

Starting Processes

启动进程

Single Process

单个进程

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

if ! tmux has-session -t "$SESSION" 2>/dev/null; then
  tmux new-session -d -s "$SESSION" -n main
  tmux send-keys -t "$SESSION:main" '<command>' Enter
else
  echo "Session $SESSION already exists"
fi
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

if ! tmux has-session -t "$SESSION" 2>/dev/null; then
  tmux new-session -d -s "$SESSION" -n main
  tmux send-keys -t "$SESSION:main" '<command>' Enter
else
  echo "Session $SESSION already exists"
fi

Adding a Window to Existing Session

向现有会话添加窗口

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

Add a new window if it doesn't exist

如果窗口不存在则添加新窗口

if ! tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^server$"; then tmux new-window -t "$SESSION" -n server tmux send-keys -t "$SESSION:server" 'npm run dev' Enter else echo "Window 'server' already exists" fi
undefined
if ! tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^server$"; then tmux new-window -t "$SESSION" -n server tmux send-keys -t "$SESSION:server" 'npm run dev' Enter else echo "Window 'server' already exists" fi
undefined

Multiple Processes (Windows)

多个进程(多窗口)

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

Create session if needed, then add windows

按需创建会话,然后添加窗口

if ! tmux has-session -t "$SESSION" 2>/dev/null; then tmux new-session -d -s "$SESSION" -n server tmux send-keys -t "$SESSION:server" 'npm run dev' Enter fi
if ! tmux has-session -t "$SESSION" 2>/dev/null; then tmux new-session -d -s "$SESSION" -n server tmux send-keys -t "$SESSION:server" 'npm run dev' Enter fi

Add more windows (idempotent)

添加更多窗口(幂等操作)

for win in tests logs; do if ! tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^${win}$"; then tmux new-window -t "$SESSION" -n "$win" fi done tmux send-keys -t "$SESSION:tests" 'npm run test:watch' Enter tmux send-keys -t "$SESSION:logs" 'tail -f logs/app.log' Enter
undefined
for win in tests logs; do if ! tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^${win}$"; then tmux new-window -t "$SESSION" -n "$win" fi done tmux send-keys -t "$SESSION:tests" 'npm run test:watch' Enter tmux send-keys -t "$SESSION:logs" 'tail -f logs/app.log' Enter
undefined

Monitoring Output

监控输出

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

Last 50 lines from first window

第一个窗口的最后50行内容

tmux capture-pane -p -t "$SESSION" -S -50
tmux capture-pane -p -t "$SESSION" -S -50

From specific window

特定窗口的内容

tmux capture-pane -p -t "$SESSION:server" -S -50
tmux capture-pane -p -t "$SESSION:server" -S -50

Check for errors

检查错误信息

tmux capture-pane -p -t "$SESSION" -S -100 | rg -i "error|fail|exception"
tmux capture-pane -p -t "$SESSION" -S -100 | rg -i "error|fail|exception"

Check for ready indicators

检查就绪标识

tmux capture-pane -p -t "$SESSION:server" -S -50 | rg -i "listening|ready|started"
undefined
tmux capture-pane -p -t "$SESSION:server" -S -50 | rg -i "listening|ready|started"
undefined

Lifecycle Management

生命周期管理

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

List all sessions (see what exists)

列出所有会话(查看已存在的会话)

tmux ls
tmux ls

List windows in current session

列出当前会话中的所有窗口

tmux list-windows -t "$SESSION"
tmux list-windows -t "$SESSION"

Kill only this project's session

仅终止当前项目的会话

tmux kill-session -t "$SESSION"
tmux kill-session -t "$SESSION"

Kill specific window

终止特定窗口

tmux kill-window -t "$SESSION:tests"
tmux kill-window -t "$SESSION:tests"

Send keys to a window (e.g., Ctrl+C to stop)

向窗口发送按键(例如,Ctrl+C停止进程)

tmux send-keys -t "$SESSION:server" C-c
undefined
tmux send-keys -t "$SESSION:server" C-c
undefined

Isolation Rules

隔离规则

  • Never use
    tmux kill-server
  • Never kill sessions not matching current project
  • Always derive session name from git root or pwd
  • Always verify session name before kill operations
  • Other Claude Code instances may have their own sessions running
  • 绝不能使用
    tmux kill-server
  • 绝不能终止与当前项目不匹配的会话
  • 始终从Git根目录或当前工作目录生成会话名称
  • 始终在执行终止操作前验证会话名称
  • 其他Claude Code实例可能在运行各自的会话

When to Use tmux

何时使用tmux

ScenarioUse tmux?
tilt up
Yes, always
Dev server (
npm run dev
,
rails s
)
Yes
File watcher (
npm run watch
)
Yes
Test watcher (
npm run test:watch
)
Yes
Database serverYes
One-shot build (
npm run build
)
No
Quick command (<10s)No
Need stdout directly in conversationNo
场景是否使用tmux?
tilt up
是,始终使用
开发服务器(
npm run dev
,
rails s
文件监控程序(
npm run watch
测试监控程序(
npm run test:watch
数据库服务器
一次性构建(
npm run build
快速命令(<10秒)
需要直接在会话中查看标准输出

Checking Process Status

检查进程状态

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

Check session exists

检查会话是否存在

tmux has-session -t "$SESSION" 2>/dev/null && echo "session exists" || echo "no session"
tmux has-session -t "$SESSION" 2>/dev/null && echo "session exists" || echo "no session"

List windows and their status

列出窗口及其状态

tmux list-windows -t "$SESSION" -F '#{window_name}: #{pane_current_command}'
tmux list-windows -t "$SESSION" -F '#{window_name}: #{pane_current_command}'

Check if specific window exists

检查特定窗口是否存在

tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^server$" && echo "server window exists"
undefined
tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^server$" && echo "server window exists"
undefined

Restarting a Process

重启进程

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

Send Ctrl+C then restart command

发送Ctrl+C然后重启命令

tmux send-keys -t "$SESSION:server" C-c sleep 1 tmux send-keys -t "$SESSION:server" 'npm run dev' Enter
undefined
tmux send-keys -t "$SESSION:server" C-c sleep 1 tmux send-keys -t "$SESSION:server" 'npm run dev' Enter
undefined

Common Patterns

常见模式

Start dev server if not running

启动未运行的开发服务器

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

if ! tmux has-session -t "$SESSION" 2>/dev/null; then
  tmux new-session -d -s "$SESSION" -n server
  tmux send-keys -t "$SESSION:server" 'npm run dev' Enter
  echo "Started dev server in tmux session: $SESSION"
elif ! tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^server$"; then
  tmux new-window -t "$SESSION" -n server
  tmux send-keys -t "$SESSION:server" 'npm run dev' Enter
  echo "Added server window to session: $SESSION"
else
  echo "Server already running in session: $SESSION"
fi
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

if ! tmux has-session -t "$SESSION" 2>/dev/null; then
  tmux new-session -d -s "$SESSION" -n server
  tmux send-keys -t "$SESSION:server" 'npm run dev' Enter
  echo "Started dev server in tmux session: $SESSION"
elif ! tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^server$"; then
  tmux new-window -t "$SESSION" -n server
  tmux send-keys -t "$SESSION:server" 'npm run dev' Enter
  echo "Added server window to session: $SESSION"
else
  echo "Server already running in session: $SESSION"
fi

Wait for server ready

等待服务器就绪

bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)
bash
SESSION=$(basename $(git rev-parse --show-toplevel 2>/dev/null) || basename $PWD)

Poll for ready message

轮询就绪消息

for i in {1..30}; do if tmux capture-pane -p -t "$SESSION:server" -S -20 | rg -q "listening|ready"; then echo "Server ready" break fi sleep 1 done
undefined
for i in {1..30}; do if tmux capture-pane -p -t "$SESSION:server" -S -20 | rg -q "listening|ready"; then echo "Server ready" break fi sleep 1 done
undefined