File size: 6,810 Bytes
db9bef5 358b846 e703e79 b94e73a 8d932ae e703e79 358b846 96645ff db9bef5 96645ff 358b846 e703e79 db9bef5 cef7f31 8d932ae 358b846 8d932ae 358b846 8d932ae 358b846 8d932ae 358b846 8d932ae 358b846 8d932ae 358b846 8d932ae 5323ea8 8d932ae 358b846 51d3b27 e501092 e7c26d6 358b846 8d932ae d36c708 e501092 e7c26d6 358b846 e501092 5323ea8 358b846 8d932ae 5323ea8 8d932ae 5323ea8 8d932ae 5323ea8 8d932ae 5323ea8 8d932ae 5323ea8 8d932ae 5323ea8 8d932ae 96645ff 8d932ae db9bef5 358b846 96645ff 8d932ae db9bef5 8d932ae fbcd0ca 8d932ae fbcd0ca 8d932ae fbcd0ca 8d932ae fbcd0ca 8d932ae 620fa8f 8d932ae 620fa8f 8d932ae fbcd0ca 8d932ae fbcd0ca 8d932ae 96645ff db9bef5 96645ff 358b846 8d932ae 96645ff 5bc200e cef7f31 96645ff 8d932ae | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | #!/bin/bash
# 打印环境变量以进行调试
echo "===== Application Startup at $(date '+%Y-%m-%d %H:%M:%S') ====="
echo "===== 应用程序启动于 $(date '+%Y-%m-%d %H:%M:%S') ====="
echo "调试信息:"
echo "WEBDAV_URL: $WEBDAV_URL"
echo "WEBDAV_USERNAME: $WEBDAV_USERNAME"
echo "WEBDAV_PASSWORD: $WEBDAV_PASSWORD"
echo "SYNC_INTERVAL: $SYNC_INTERVAL"
# 检查必要的环境变量
if [ -z "$WEBDAV_URL" ] || [ -z "$WEBDAV_USERNAME" ] || [ -z "$WEBDAV_PASSWORD" ]; then
echo "缺少必要的环境变量 WEBDAV_URL、WEBDAV_USERNAME 或 WEBDAV_PASSWORD"
exit 1
fi
# 创建数据目录
mkdir -p ./data
# 定义上传函数,包含MD5校验和重试逻辑
upload_with_verification() {
local source_file="$1"
local target_url="$2"
local max_retries=3
local retry_count=0
local success=false
while [ $retry_count -lt $max_retries ] && [ "$success" = false ]; do
# 计算源文件的MD5
local local_md5=$(md5sum "$source_file" | cut -d' ' -f1)
echo "本地文件 MD5: $local_md5"
# 上传文件
if curl -L -f --connect-timeout 30 --max-time 600 \
-T "$source_file" \
--user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" \
"$target_url"; then
# 等待一小段时间确保文件已完全写入服务器
sleep 5
# 获取远程文件的MD5
local remote_md5=$(curl -s -L --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" \
"$target_url" | md5sum | cut -d' ' -f1)
echo "远程文件 MD5: $remote_md5"
if [ "$local_md5" = "$remote_md5" ]; then
echo "MD5校验通过"
success=true
break
else
echo "MD5校验失败,准备重试..."
retry_count=$((retry_count + 1))
if [ $retry_count -lt $max_retries ]; then
echo "等待30秒后进行第 $((retry_count + 1)) 次重试..."
sleep 30
fi
fi
else
echo "上传失败,准备重试..."
retry_count=$((retry_count + 1))
if [ $retry_count -lt $max_retries ]; then
echo "等待30秒后进行第 $((retry_count + 1)) 次重试..."
sleep 30
fi
fi
done
if [ "$success" = true ]; then
return 0
else
return 1
fi
}
# 定义函数:清理 TeraCloud 网盘中的旧文件
clean_remote_files() {
echo "正在清理 TeraCloud 网盘中的旧文件..."
# 发送 PROPFIND 请求列出 WebDAV 文件
RESPONSE=$(curl -s -L -X PROPFIND --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" -H "Depth: 1" "$WEBDAV_URL")
if [ -z "$RESPONSE" ]; then
echo "无法获取 WebDAV 文件列表"
return
fi
# 使用 xmlstarlet 解析 XML 响应,提取文件名
FILE_LIST=$(echo "$RESPONSE" | xmlstarlet sel -N d="DAV:" -t -v "//d:href/text()" 2>/dev/null | sed 's|.*/||')
if [ -z "$FILE_LIST" ]; then
echo "未找到文件"
return
fi
# 过滤出带有时间戳的文件
TIMESTAMPED_FILES=$(echo "$FILE_LIST" | grep -E '^webui_[0-9]{2}_[0-9]{2}_[0-9]{4}\.db$')
if [ -z "$TIMESTAMPED_FILES" ]; then
echo "未找到带有时间戳的文件,跳过清理"
return
fi
# 按文件名排序
SORTED_FILES=$(echo "$TIMESTAMPED_FILES" | sort -r)
# 保留最新的一个文件,删除其他旧文件
COUNT=0
for FILE in $SORTED_FILES; do
COUNT=$((COUNT + 1))
if [ $COUNT -gt 1 ]; then
echo "删除旧文件: $FILE"
curl -X DELETE --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/$FILE" || {
echo "删除失败: $FILE"
}
else
echo "保留最新文件: $FILE"
fi
done
echo "TeraCloud 网盘清理完成"
}
# 在第一次运行时清理 TeraCloud 网盘中的旧文件
clean_remote_files
# 从 WebDAV 下载 webui.db 文件
echo "正在从 WebDAV 下载数据库文件..."
if ! curl -L -f --user "$WEBDAV_USERNAME:$WEBDAV_PASSWORD" "$WEBDAV_URL/webui.db" -o "./data/webui.db"; then
echo "下载失败,脚本退出"
exit 1
fi
echo "下载成功"
# 定义同步函数
sync_data() {
# 首次等待同步间隔
SYNC_INTERVAL=${SYNC_INTERVAL:-7200}
echo "初始下载完成,等待 ${SYNC_INTERVAL} 秒后开始同步..."
sleep $SYNC_INTERVAL
while true; do
echo "正在开始同步"
if [ -f "./data/webui.db" ]; then
# 检查是否安装了 sqlite3 命令,如果安装了,执行 WAL checkpoint
if command -v sqlite3 &> /dev/null; then
echo "执行 SQLite WAL checkpoint 以确保数据一致性..."
sqlite3 "./data/webui.db" "PRAGMA wal_checkpoint(TRUNCATE);"
else
echo "未找到 sqlite3 命令,跳过 SQLite WAL checkpoint."
fi
# 创建临时副本以避免文件写入冲突
TIMESTAMP=$(date +%s)
TEMP_FILE="./data/webui_temp_${TIMESTAMP}.db"
if ! cp "./data/webui.db" "$TEMP_FILE"; then
echo "复制数据库文件失败,跳过本次同步"
continue
fi
# 生成当前时间的文件名
FILENAME="webui_$(date +'%m_%d_%H%M').db"
echo "同步到 WebDAV: $FILENAME"
# 使用带验证的上传函数上传文件
if upload_with_verification "$TEMP_FILE" "$WEBDAV_URL/$FILENAME"; then
echo "文件 $FILENAME 上传成功"
# 更新主文件 webui.db
if upload_with_verification "$TEMP_FILE" "$WEBDAV_URL/webui.db"; then
echo "主文件 webui.db 更新成功"
else
echo "主文件 webui.db 更新失败"
fi
else
echo "文件 $FILENAME 上传失败"
fi
# 删除临时副本
rm -f "$TEMP_FILE"
# 清理远程旧文件
clean_remote_files
# 清理本地旧文件(保留最新3个)
echo "清理本地旧备份..."
find "./data" -name "webui_*.db" -type f -printf "%T@ %p\n" | \
sort -rn | tail -n +4 | cut -d' ' -f2- | xargs rm -f
echo "本地备份清理完成"
else
echo "未找到 webui.db 文件,跳过同步"
fi
echo "当前时间 $(date '+%Y-%m-%d %H:%M:%S')"
echo "等待 ${SYNC_INTERVAL} 秒后进行下一次同步..."
sleep $SYNC_INTERVAL
done
}
# 后台启动同步进程
sync_data & |