#!/usr/bin/env bash set -euo pipefail ######################################## # 配置区(可按需修改) ######################################## RETRIES=5 # 额外重试次数(总尝试 = RETRIES+1) BACKOFF_BASE=2 # 回退基数(秒),指数回退:base^(attempt-1) CACHE_CONTROL="no-store" # 上传时写入的 Cache-Control bucket="plugai" host="https://s3.szaiai.com" # 最终给用户的下载前缀 endpoint="https://api.szaiai.com" # MinIO S3 端点 access_key="admin" secret_key="Admin@123.." alias="autoalias" ######################################## # 参数 & 预检 ######################################## if [ $# -ne 1 ]; then echo "用法: $0 <本地文件路径>" >&2 exit 1 fi file="$1" [ -f "$file" ] || { echo "❌ 文件不存在: $file"; exit 1; } command -v mc >/dev/null || { echo "❌ 未找到 mc 命令"; exit 1; } command -v sha256sum >/dev/null || { echo "❌ 未找到 sha256sum"; exit 1; } ######################################## # 准备 alias / bucket ######################################## mc alias rm "$alias" 2>/dev/null || true mc alias set "$alias" "$endpoint" "$access_key" "$secret_key" >/dev/null mc mb --ignore-existing "$alias/$bucket" >/dev/null filename=$(basename -- "$file") encoded_name=$(python3 - <<'PY' import urllib.parse,sys print(urllib.parse.quote(sys.argv[1])) PY "$filename") local_hash=$(sha256sum "$file" | awk '{print $1}') local_size=$(stat -c %s "$file") echo "➡️ 开始上传:$filename (size=${local_size} bytes, sha256=$local_hash)" ######################################## # 函数:单次上传 + 校验 ######################################## upload_and_verify() { # 上传(覆盖),加 Cache-Control 避免旧缓存 mc cp --attr "Cache-Control=${CACHE_CONTROL}" "$file" "$alias/$bucket/$filename" >/dev/null # 远端拉回做哈希对比 remote_hash=$(mc cat "$alias/$bucket/$filename" | sha256sum | awk '{print $1}') remote_size=$(mc stat --json "$alias/$bucket/$filename" | awk -F'"' '/"size"/{print $4;exit}') if [ "$remote_size" != "$local_size" ]; then echo "⚠️ 远端大小不一致: local=$local_size remote=$remote_size" return 1 fi if [ "$remote_hash" != "$local_hash" ]; then echo "⚠️ 哈希不一致: local=$local_hash remote=$remote_hash" return 1 fi return 0 } ######################################## # 重试逻辑 ######################################## attempt=0 while true; do attempt=$((attempt+1)) if upload_and_verify; then echo "✅ 上传校验成功:$host/$bucket/$encoded_name" exit 0 fi if [ $attempt -gt $((RETRIES+1)) ]; then echo "❌ 全部尝试失败(尝试次数: $((attempt-1))),放弃。" exit 1 fi # 退避等待 sleep_sec=$(( BACKOFF_BASE ** (attempt-1) )) echo "🔁 第 $attempt 次失败,$sleep_sec 秒后重试(剩余可重试:$((RETRIES - attempt + 1)))..." sleep "$sleep_sec" done