tmux进程管理Skill tmux-processes

tmux进程管理技能文档,详细介绍了在tmux终端复用器中管理长生命周期进程的最佳实践和模式。包括会话命名规范、进程启动方法、输出监控、生命周期管理、隔离规则等。适用于开发服务器、文件监视器、测试运行器等场景。关键词:tmux进程管理,终端复用,开发服务器管理,进程监控,会话管理,DevOps工具,命令行工具,后台进程管理。

DevOps 0 次安装 0 次浏览 更新于 2/28/2026

name: tmux-processes description: 在tmux中运行长生命周期进程的模式。适用于启动开发服务器、文件监视器、tilt或任何预期会持续运行的进程。

tmux进程管理

交互式Shell要求

使用send-keys模式确保可靠的shell初始化。 创建会话时会自动生成交互式shell。使用send-keys在该shell中运行命令,确保PATH、direnv和其他初始化正确执行。

# 错误 - 内联命令绕过shell初始化,破坏PATH/direnv
tmux new-session -d -s "$SESSION" -n main 'tilt up'

# 正确 - 创建会话,然后向交互式shell发送命令
tmux new-session -d -s "$SESSION" -n main
tmux send-keys -t "$SESSION:main" 'tilt up' Enter

会话命名规范

始终从项目派生会话名称:

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

对于单个项目中的多个进程,使用窗口而非单独会话:

  • 会话:myapp
  • 窗口:servertestslogs

启动进程

单个进程

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

# 创建带命名窗口的会话,然后发送命令
tmux new-session -d -s "$SESSION" -n main
tmux send-keys -t "$SESSION:main" '<命令>' Enter

幂等启动

启动前检查是否已在运行:

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" '<命令>' Enter
else
  echo "会话 $SESSION 已存在"
fi

向现有会话添加窗口

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

# 如果窗口不存在则添加新窗口
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 "窗口 'server' 已存在"
fi

多个进程(窗口)

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

# 创建带第一个进程的会话
tmux new-session -d -s "$SESSION" -n server
tmux send-keys -t "$SESSION:server" 'npm run dev' Enter

# 添加更多窗口
tmux new-window -t "$SESSION" -n tests
tmux send-keys -t "$SESSION:tests" 'npm run test:watch' Enter

tmux new-window -t "$SESSION" -n logs
tmux send-keys -t "$SESSION:logs" 'tail -f logs/app.log' Enter

监控输出

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

# 从第一个窗口获取最后50行
tmux capture-pane -p -t "$SESSION" -S -50

# 从特定窗口获取
tmux capture-pane -p -t "$SESSION:server" -S -50

# 检查错误
tmux capture-pane -p -t "$SESSION" -S -100 | rg -i "error|fail|exception"

# 检查就绪指示器
tmux capture-pane -p -t "$SESSION:server" -S -50 | rg -i "listening|ready|started"

生命周期管理

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

# 列出所有会话(查看存在哪些)
tmux ls

# 列出当前会话中的窗口
tmux list-windows -t "$SESSION"

# 仅终止此项目的会话
tmux kill-session -t "$SESSION"

# 终止特定窗口
tmux kill-window -t "$SESSION:tests"

# 向窗口发送按键(例如,Ctrl+C停止)
tmux send-keys -t "$SESSION:server" C-c

隔离规则

  • 绝不使用tmux kill-server
  • 绝不终止不匹配当前项目的会话
  • 始终从git根目录或pwd派生会话名称
  • 始终在终止操作前验证会话名称
  • 其他Claude Code实例可能运行自己的会话

何时使用tmux

场景 使用tmux?
tilt up 是,始终
开发服务器(npm run devrails s
文件监视器(npm run watch
测试监视器(npm run test:watch
数据库服务器
一次性构建(npm run build
快速命令(<10秒)
需要在对话中直接查看stdout

检查进程状态

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

# 检查会话是否存在
tmux has-session -t "$SESSION" 2>/dev/null && echo "会话存在" || echo "无会话"

# 列出窗口及其状态
tmux list-windows -t "$SESSION" -F '#{window_name}: #{pane_current_command}'

# 检查特定窗口是否存在
tmux list-windows -t "$SESSION" -F '#{window_name}' | grep -q "^server$" && echo "服务器窗口存在"

重启进程

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

# 发送Ctrl+C然后重启命令
tmux send-keys -t "$SESSION:server" C-c
sleep 1
tmux send-keys -t "$SESSION:server" 'npm run dev' Enter

常见模式

如果未运行则启动开发服务器

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 "在tmux会话中启动开发服务器:$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 "向会话添加服务器窗口:$SESSION"
else
  echo "服务器已在会话中运行:$SESSION"
fi

等待服务器就绪

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

# 轮询就绪消息
for i in {1..30}; do
  if tmux capture-pane -p -t "$SESSION:server" -S -20 | rg -q "listening|ready"; then
    echo "服务器就绪"
    break
  fi
  sleep 1
done