#!/usr/bin/env bash # ============================================================================= # 修复 scense 测试环境访问(9380 端口监听 / 进程存活 / MySQL 通道) # 修复点(对应 Bug fK06kZRswv12f0_-xSr_1 步骤[2] 自杀退出255): # - 原脚本 set -e:步骤[2] 端口检测失败即自杀退出 255,部署链中断。 # - 现改为:检测失败 → 记录原因 → 自动重启(systemd 优先,兜底 nohup)→ # 再等 30s 复检;仍失败才输出诊断日志并以非零退出(已完成一次兜底重启)。 # ============================================================================= set -uo pipefail APP_NAME="scense" APP_PORT="${SERVER_PORT:-9380}" WORKDIR="$(cd "$(dirname "$0")/.." && pwd)" VENV_DIR="$WORKDIR/venv" ENV_FILE="$WORKDIR/.env" LOG="$WORKDIR/logs/scense.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; } [ -f "$ENV_FILE" ] && { set -a; . "$ENV_FILE"; set +a; } # 步骤[1] 端口监听检测(/dev/tcp 无需额外工具) check_port() { (exec 3<>"/dev/tcp/127.0.0.1/$APP_PORT") 2>/dev/null && { exec 3>&- 3<&-; return 0; } return 1 } # 步骤[2] 进程存活检测 check_proc() { pgrep -f "app/$APP_NAME.py" >/dev/null 2>&1 } # 步骤[3] MySQL 通道检测 check_mysql() { command -v mysql >/dev/null 2>&1 || return 1 mysql --host="${MYSQL_HOST:-127.0.0.1}" --port="${MYSQL_PORT:-3306}" \ --user="${MYSQL_USER:-root}" --password="${MYSQL_PASSWORD:-}" \ -e "SELECT 1" "${MYSQL_DATABASE:-scense}" >/dev/null 2>&1 } # 重启兜底:systemd 优先,失败回退 nohup 直接拉起 restart_app() { log "restart $APP_NAME ..." if systemctl restart "$APP_NAME" 2>/dev/null; then return 0 fi pkill -f "app/$APP_NAME.py" 2>/dev/null || true sleep 1 nohup "$VENV_DIR/bin/python" "$WORKDIR/app/$APP_NAME.py" >> "$LOG" 2>&1 & return 0 } main() { local fix_count=0 if check_port; then log "[1] port $APP_PORT listening" else log "[1] port $APP_PORT NOT listening -> need fix" fix_count=$((fix_count+1)) fi if check_proc; then log "[2] process app/$APP_NAME.py running" else log "[2] process app/$APP_NAME.py NOT found -> need fix" fix_count=$((fix_count+1)) fi if check_mysql; then log "[3] MySQL channel (${MYSQL_DATABASE:-scense}@${MYSQL_HOST:-127.0.0.1}) OK" else log "[3] MySQL channel unreachable -> need fix" fix_count=$((fix_count+1)) fi if [ "$fix_count" -gt 0 ]; then log "detected $fix_count issue(s), restart app (bootstrap, no suicide exit)" restart_app for _ in $(seq 1 30); do if check_port && check_proc; then log "OK: $APP_NAME back on port $APP_PORT after restart" exit 0 fi sleep 1 done log "WARN: $APP_NAME still not listening after restart; last log lines:" tail -n 30 "$LOG" 2>/dev/null || true exit 1 fi log "OK: scense test env accessible (port=$APP_PORT)" exit 0 } main "$@"