#!/bin/bash # 「风扇区布局 × 可布性」联合扫描的服务器入口(CLAUDE.md:布线搜索一律上 10.5.5.13)。 # # bash .claude/r2/remote_fan_layout.sh # # 前置(本机生成):_base_fan_input.json(板上现有铜)、_base_fan_layouts.json(几套候选布局)、 # _base_pads.json(当前焊盘表)。 # 回来的是 _base_fan_layout_scan.json:最优布局 + 它那一版的完整补线段 / 孔。 set -euo pipefail SERVER="${SERVER:-10.5.5.13}" INTERP="${INTERP:-/root/pypy/bin/pypy3}" SSH="${SSH:-/c/Windows/System32/OpenSSH/ssh.exe}" SCP="${SCP:-/c/Windows/System32/OpenSSH/scp.exe}" HERE="$(cd "$(dirname "$0")" && pwd)" REPO="$(cd "$HERE/../.." && pwd)" for f in _base_fan_input.json _base_fan_layouts.json _base_pads.json; do [ -f "$HERE/$f" ] || { echo "⛔ 缺 $f" >&2; exit 1; } done ARCHIVE="$(mktemp -t dcdc-fanlayout-XXXXXX)" cd "$REPO" tar --exclude='*.png' --exclude='*.bak' --exclude=__pycache__ --exclude='_remote_route.tgz' \ -czf "$ARCHIVE" .claude/r2 .claude/eda.py .claude/pcb_pour.py .claude/eda-parts.json REMOTE="$("$SSH" "$SERVER" 'mktemp -d /tmp/dcdc-fanlayout.XXXXXX' | tr -d '\r\n')" case "$REMOTE" in /tmp/dcdc-fanlayout.*) ;; *) echo "⛔ 远端工作目录不对: $REMOTE" >&2; rm -f "$ARCHIVE"; exit 1 ;; esac cleanup() { rm -f "$ARCHIVE"; "$SSH" "$SERVER" "rm -rf -- '$REMOTE'" >/dev/null 2>&1 || true; } trap cleanup EXIT "$SCP" -q "$ARCHIVE" "$SERVER:$REMOTE/bundle.tgz" "$SSH" "$SERVER" "tar -xzf '$REMOTE/bundle.tgz' -C '$REMOTE'" echo "== 服务器 $SERVER 上扫布局 ==" "$SSH" "$SERVER" "cd '$REMOTE' && DCDC_ROUTE_SERVER=1 \ /usr/bin/time -f 'REMOTE_TIME=%e sec CPU=%P RSS=%M KB' $INTERP .claude/r2/fan_layout_scan.py" "$SCP" -q "$SERVER:$REMOTE/.claude/r2/_base_fan_layout_scan.json" "$HERE/_base_fan_layout_scan.json" echo "已取回 $HERE/_base_fan_layout_scan.json"