#!/bin/sh # /etc/init.d/S99archery # 系统启动时处理致命错误恢复(仅处理无法启动的情况) # 注意:应用的启动由系统自动启动机制处理(通过 auto_start.txt) # 功能: # 1. 处理致命错误(无法启动)- 恢复 main.py # 2. 如果重启次数超过阈值,恢复 main.py 并重启系统 APP_DIR="/maixapp/apps/t11" MAIN_PY="$APP_DIR/main.py" PENDING_FILE="$APP_DIR/ota_pending.json" BACKUP_BASE="$APP_DIR/backups" # 进入应用目录 cd "$APP_DIR" || exit 0 # 检查 pending 文件,如果存在且超过重启次数,恢复 main.py(处理致命错误) if [ -f "$PENDING_FILE" ]; then echo "[S99] 检测到 ota_pending.json,检查重启计数..." # 尝试从JSON中提取重启计数(使用grep简单提取) RESTART_COUNT=$(cat "$PENDING_FILE" 2>/dev/null | grep -o '"restart_count":[0-9]*' | grep -o '[0-9]*' || echo "0") MAX_RESTARTS=$(cat "$PENDING_FILE" 2>/dev/null | grep -o '"max_restarts":[0-9]*' | grep -o '[0-9]*' || echo "3") if [ -n "$RESTART_COUNT" ] && [ "$RESTART_COUNT" -ge "$MAX_RESTARTS" ]; then echo "[S99] 检测到重启次数 ($RESTART_COUNT) 超过阈值 ($MAX_RESTARTS),恢复 main.py..." # 尝试从JSON中提取备份目录 BACKUP_DIR=$(cat "$PENDING_FILE" 2>/dev/null | grep -o '"backup_dir":"[^"]*"' | grep -o '/[^"]*' || echo "") if [ -n "$BACKUP_DIR" ] && [ -f "$BACKUP_DIR/main.py" ]; then # 使用指定的备份目录 echo "[S99] 从备份目录恢复: $BACKUP_DIR/main.py" cp "$BACKUP_DIR/main.py" "$MAIN_PY" 2>/dev/null && echo "[S99] 已恢复 main.py" else # 查找最新的备份目录 LATEST_BACKUP=$(ls -dt "$BACKUP_BASE"/backup_* 2>/dev/null | head -1) if [ -n "$LATEST_BACKUP" ] && [ -f "$LATEST_BACKUP/main.py" ]; then echo "[S99] 从最新备份恢复: $LATEST_BACKUP/main.py" cp "$LATEST_BACKUP/main.py" "$MAIN_PY" 2>/dev/null && echo "[S99] 已恢复 main.py" else # 如果没有备份目录,尝试使用 main.py.bak if [ -f "$APP_DIR/main.py.bak" ]; then echo "[S99] 从 main.py.bak 恢复" cp "$APP_DIR/main.py.bak" "$MAIN_PY" 2>/dev/null && echo "[S99] 已恢复 main.py" fi fi fi # 恢复后重置重启计数,避免循环恢复 # 注意:不在这里删除 pending 文件,让 main.py 在心跳成功后删除 # 但是重置重启计数,以便恢复后的版本可以重新开始计数 python3 -c " import json, os try: pending_path = '$PENDING_FILE' if os.path.exists(pending_path): with open(pending_path, 'r', encoding='utf-8') as f: d = json.load(f) d['restart_count'] = 0 # 重置重启计数 with open(pending_path, 'w', encoding='utf-8') as f: json.dump(d, f) print('[S99] 已重置重启计数为 0') except Exception as e: print(f'[S99] 重置重启计数失败: {e}') " 2>/dev/null || echo "[S99] 无法重置重启计数(可能需要Python支持)" echo "[S99] 已恢复 main.py,重启系统..." echo "[S99] 注意:pending 文件将在心跳成功后由 main.py 删除" sleep 2 reboot exit 0 fi fi # 不启动应用,让系统自动启动机制处理 # 这个脚本只负责处理致命错误恢复 exit 0