This commit is contained in:
parent
6f02133d0d
commit
f5e9496591
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 用法提示
|
||||||
|
if [ $# -lt 1 ]; then
|
||||||
|
echo "❌ 用法: $0 <本地文件路径>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === 用户可配置部分 ===
|
||||||
|
file="$1"
|
||||||
|
bucket="plugai"
|
||||||
|
host="https://s3.szaiai.com" # 下载链接前缀
|
||||||
|
endpoint="https://api.szaiai.com" # MinIO 的 S3 API 访问地址
|
||||||
|
access_key="admin"
|
||||||
|
secret_key="Admin@123.."
|
||||||
|
alias="autoalias"
|
||||||
|
|
||||||
|
# === 检查文件是否存在 ===
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
|
echo "❌ 文件不存在: $file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# === 设置 alias(自动覆盖旧的) ===
|
||||||
|
mc alias rm $alias 2>/dev/null
|
||||||
|
mc alias set $alias $endpoint $access_key $secret_key > /dev/null
|
||||||
|
|
||||||
|
# === 确保目标 bucket 存在(如果不存在则创建) ===
|
||||||
|
mc mb --ignore-existing "$alias/$bucket" > /dev/null
|
||||||
|
|
||||||
|
# === 上传文件 ===
|
||||||
|
filename=$(basename "$file")
|
||||||
|
if mc cp "$file" "$alias/$bucket/$filename"; then
|
||||||
|
encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('''$filename'''))")
|
||||||
|
echo "✅ 上传成功:$host/$bucket/$encoded"
|
||||||
|
else
|
||||||
|
echo "❌ 上传失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
@ -1,40 +1,91 @@
|
||||||
#!/bin/bash
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
# 用法提示
|
########################################
|
||||||
if [ $# -lt 1 ]; then
|
# 配置区(可按需修改)
|
||||||
echo "❌ 用法: $0 <本地文件路径>"
|
########################################
|
||||||
exit 1
|
RETRIES=5 # 额外重试次数(总尝试 = RETRIES+1)
|
||||||
fi
|
BACKOFF_BASE=2 # 回退基数(秒),指数回退:base^(attempt-1)
|
||||||
|
CACHE_CONTROL="no-store" # 上传时写入的 Cache-Control
|
||||||
# === 用户可配置部分 ===
|
|
||||||
file="$1"
|
|
||||||
bucket="plugai"
|
bucket="plugai"
|
||||||
host="https://s3.szaiai.com" # 下载链接前缀
|
host="https://s3.szaiai.com" # 最终给用户的下载前缀
|
||||||
endpoint="https://api.szaiai.com" # MinIO 的 S3 API 访问地址
|
endpoint="https://api.szaiai.com" # MinIO S3 端点
|
||||||
access_key="admin"
|
access_key="admin"
|
||||||
secret_key="Admin@123.."
|
secret_key="Admin@123.."
|
||||||
alias="autoalias"
|
alias="autoalias"
|
||||||
|
|
||||||
# === 检查文件是否存在 ===
|
########################################
|
||||||
if [ ! -f "$file" ]; then
|
# 参数 & 预检
|
||||||
echo "❌ 文件不存在: $file"
|
########################################
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
echo "用法: $0 <本地文件路径>" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# === 设置 alias(自动覆盖旧的) ===
|
file="$1"
|
||||||
mc alias rm $alias 2>/dev/null
|
[ -f "$file" ] || { echo "❌ 文件不存在: $file"; exit 1; }
|
||||||
mc alias set $alias $endpoint $access_key $secret_key > /dev/null
|
command -v mc >/dev/null || { echo "❌ 未找到 mc 命令"; exit 1; }
|
||||||
|
command -v sha256sum >/dev/null || { echo "❌ 未找到 sha256sum"; exit 1; }
|
||||||
|
|
||||||
# === 确保目标 bucket 存在(如果不存在则创建) ===
|
########################################
|
||||||
mc mb --ignore-existing "$alias/$bucket" > /dev/null
|
# 准备 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")
|
||||||
filename=$(basename "$file")
|
encoded_name=$(python3 - <<'PY'
|
||||||
if mc cp "$file" "$alias/$bucket/$filename"; then
|
import urllib.parse,sys
|
||||||
encoded=$(python3 -c "import urllib.parse; print(urllib.parse.quote('''$filename'''))")
|
print(urllib.parse.quote(sys.argv[1]))
|
||||||
echo "✅ 上传成功:$host/$bucket/$encoded"
|
PY
|
||||||
else
|
"$filename")
|
||||||
echo "❌ 上传失败"
|
|
||||||
|
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
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 退避等待
|
||||||
|
sleep_sec=$(( BACKOFF_BASE ** (attempt-1) ))
|
||||||
|
echo "🔁 第 $attempt 次失败,$sleep_sec 秒后重试(剩余可重试:$((RETRIES - attempt + 1)))..."
|
||||||
|
sleep "$sleep_sec"
|
||||||
|
done
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue