#!/bin/sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) INFRA_DIR=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd) PROJECT_DIR=$(CDPATH= cd -- "$INFRA_DIR/.." && pwd) BACKUP_ROOT=${BACKUP_ROOT:-"$PROJECT_DIR/backups"} RETENTION_DAYS=${BACKUP_RETENTION_DAYS:-30} case "$RETENTION_DAYS" in *[!0-9]*|"") echo "BACKUP_RETENTION_DAYS 必须是正整数" >&2; exit 2 ;; esac if [ "$RETENTION_DAYS" -lt 1 ]; then echo "BACKUP_RETENTION_DAYS 必须至少为 1" >&2 exit 2 fi mkdir -p "$BACKUP_ROOT" BACKUP_ROOT=$(CDPATH= cd -- "$BACKUP_ROOT" && pwd) case "$BACKUP_ROOT" in "$PROJECT_DIR/backups"|"$PROJECT_DIR/backups/"*) ;; *) echo "拒绝清理项目 backups 目录之外的路径:$BACKUP_ROOT" >&2; exit 2 ;; esac find "$BACKUP_ROOT" -mindepth 1 -maxdepth 1 -type d -mtime "+$RETENTION_DAYS" -print | while IFS= read -r candidate; do name=$(basename "$candidate") if ! printf '%s\n' "$name" | grep -Eq '^20[0-9]{6}T[0-9]{6}Z$'; then echo "跳过非标准备份目录:$candidate" continue fi if [ ! -f "$candidate/manifest.txt" ] || [ ! -f "$candidate/SHA256SUMS" ]; then echo "跳过缺少清单的目录:$candidate" continue fi rm -rf -- "$candidate" echo "已按保留策略删除:$candidate" done