#!/usr/bin/env bash # 接口11(发际线生发)所需的 change_hair 后端服务启停脚本。 # # webui(57860) + photo_service(32678) + hair_service_sd(8801) # —— 不需要 ComfyUI。 # # hair_service_sd 会被【强制重启】以加载接口11 的 ext_mask 改动; # webui / photo_service 仅在未运行时才拉起(已在跑则不动,避免 webui 重新加载模型)。 # # 用法: # bash scripts/restart_if11_backends.sh # 确保三个服务就绪(强制重启 8801) # bash scripts/restart_if11_backends.sh status # 只看状态 set -u PROJ="/home/xsl/change_hair/project" LOGDIR="$PROJ/logs" PIDD="$LOGDIR/pids" PY_SD="/home/xsl/miniconda3/envs/sdwebui/bin/python" PY_PHOTO="/home/xsl/miniconda3/envs/py310/bin/python" PY_HAIR="/home/xsl/miniconda3/envs/my_hair/bin/python" mkdir -p "$LOGDIR" "$PIDD" export CRYPTOGRAPHY_OPENSSL_NO_LEGACY=1 export CUDA_VISIBLE_DEVICES=0 export APP_WORKER_ID=1 port_up() { ss -ltn 2>/dev/null | grep -q ":$1 "; } wait_port() { # $1=port $2=label $3=timeout_s local p="$1" label="$2" to="${3:-90}" i=0 echo -n " 等待 $label (端口 $p) " while [ "$i" -lt "$to" ]; do if port_up "$p"; then echo " ✓ 就绪"; return 0; fi echo -n "."; sleep 2; i=$((i+2)) done echo " ✗ 超时(看日志:$LOGDIR/*.log)"; return 1 } status() { echo "=== 服务状态 $(date '+%H:%M:%S') ===" for pair in "webui:57860" "photo_service:32678" "hair_service_sd:8801"; do local name="${pair%%:*}" port="${pair##*:}" if port_up "$port"; then echo " ✓ $name (端口 $port 就绪)"; else echo " ✗ $name (端口 $port 未监听)"; fi done echo " worker 8187: $(curl -s -m3 http://127.0.0.1:8187/health 2>/dev/null || echo '未响应')" } if [ "${1:-}" = "status" ]; then status; exit 0; fi # 1) webui —— 仅未运行时启动(模型加载慢,别乱重启) if pgrep -f "webui.py.*57860" >/dev/null; then echo "webui 已在运行,跳过" else echo "启动 webui (57860)..." ( cd "$PROJ/onediff/stable-diffusion-webui" && \ HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 \ nohup "$PY_SD" webui.py --api --listen --xformers --port 57860 > "$LOGDIR/webui.log" 2>&1 & \ echo $! > "$PIDD/webui.pid" ) echo " webui PID=$(cat "$PIDD/webui.pid" 2>/dev/null)" fi # 2) photo_service —— 仅未运行时启动 if pgrep -f "lora_train_service_1.py" >/dev/null; then echo "photo_service 已在运行,跳过" else echo "启动 photo_service (32678)..." ( cd "$PROJ/photo_service" && \ nohup "$PY_PHOTO" -u lora_train_service_1.py > "$LOGDIR/photo_service.log" 2>&1 & \ echo $! > "$PIDD/photo_service.pid" ) echo " photo_service PID=$(cat "$PIDD/photo_service.pid" 2>/dev/null)" fi # 3) hair_service_sd —— 强制重启(加载接口11 的 ext_mask 改动) echo "强制重启 hair_service_sd (8801)..." pkill -f "run_copy_cost_colorb64" 2>/dev/null sleep 2 ( cd "$PROJ/hair_service_sd" && \ nohup "$PY_HAIR" run_copy_cost_colorb64.py > "$LOGDIR/hair_service_if11.log" 2>&1 & \ echo $! > "$PIDD/hair_service.pid" ) echo " hair_service_sd PID=$(cat "$PIDD/hair_service.pid" 2>/dev/null)" echo "--- 等待就绪 ---" wait_port 57860 webui 180 wait_port 32678 photo_service 60 wait_port 8801 hair_service_sd 120 echo status echo echo "提示:hair_service_sd 端口就绪后,模型可能还需几秒;日志出现 '[HAIR_INIT] All init done' 即完全可用:" echo " tail -f $LOGDIR/hair_service_if11.log"