编写脚本

This commit is contained in:
LiuEnder
2026-05-07 21:33:36 +08:00
parent 3c29415e94
commit bfc1aa87f2
2 changed files with 202 additions and 1 deletions

View File

@@ -2,13 +2,22 @@
## 功能
每天从https://git.ociflab.icu/Laplace/backup-list拉取whitelist.md
如果没拉取到则使用前一天拉取并保存的whitelist文件。
如果超过三分之一的仓库都拉取错误则给脚本中设置的server酱3 Pushkey推送警告信息。
然后根据whitelist.md拉取对应的仓库到backup文件夹进行备份
压缩成zip每天定时备份一次保留7天。
使用Python
使用bash
## whitelist.md文件结构
~~~
https://git.ociflab.icu/userA/projectA
https://git.ociflab.icu/userB/projectB
~~~
## server酱3参考
~~~bash
# 一行代码即可调用中文参数需要UrlEncode长内容建议使用POST
curl "https://<uid>.push.ft07.com/send/<sendkey>.send?title=<title>&desp=<desp>"
~~~

192
ociflab-backup.sh Normal file
View File

@@ -0,0 +1,192 @@
#!/bin/bash
set -euo pipefail
# ============================================================
# OCIFLAB 仓库备份脚本
# 每天从 whitelist.md 拉取仓库列表,克隆/更新仓库,压缩备份
# ============================================================
# ---------- 配置区 ----------
WHITELIST_URL=""
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKUP_DIR="${SCRIPT_DIR}/backup"
WORK_DIR="${SCRIPT_DIR}/work"
ARCHIVE_DIR="${SCRIPT_DIR}/archives"
WHITELIST_CACHE="${SCRIPT_DIR}/whitelist_cache.md"
RETENTION_DAYS=7
DATE_STAMP="$(date +%Y%m%d)"
# server酱3 配置
SERVERCHAN_UID="" # 填写你的 UID
SERVERCHAN_SENDKEY="" # 填写你的 SendKey
# ---------- 函数区 ----------
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
send_warning() {
local title="$1"
local desp="$2"
if [[ -z "${SERVERCHAN_UID}" ]] || [[ -z "${SERVERCHAN_SENDKEY}" ]]; then
log "server酱未配置跳过推送: ${title}"
return 0
fi
local resp
resp=$(curl -s -o /dev/null -w "%{http_code}" --data-urlencode "title=${title}" --data-urlencode "desp=${desp}" "https://${SERVERCHAN_UID}.push.ft07.com/send/${SERVERCHAN_SENDKEY}.send")
if [[ "${resp}" == "200" ]]; then
log "警告推送成功: ${title}"
else
log "警告推送失败(HTTP ${resp}): ${title}"
fi
}
fetch_whitelist() {
log "正在拉取 whitelist.md ..."
local http_code
http_code=$(curl -s -o "${WHITELIST_CACHE}" -w "%{http_code}" --connect-timeout 10 --max-time 30 "${WHITELIST_URL}")
if [[ "${http_code}" == "200" ]] && [[ -s "${WHITELIST_CACHE}" ]]; then
log "whitelist.md 拉取成功 (HTTP ${http_code})"
return 0
fi
log "whitelist.md 拉取失败 (HTTP ${http_code}),尝试使用前一天缓存..."
if [[ -f "${SCRIPT_DIR}/whitelist_cache.md.yesterday" ]]; then
cp "${SCRIPT_DIR}/whitelist_cache.md.yesterday" "${WHITELIST_CACHE}"
log "已使用前一天缓存"
return 0
fi
log "前一天缓存也不存在,无法继续"
return 1
}
parse_whitelist() {
grep -Eo 'https://git\.ociflab\.icu/[^[:space:]]+' "${WHITELIST_CACHE}" | sed 's/[[:space:]]*$//'
}
clone_or_pull_repo() {
local repo_url="$1"
local repo_name
repo_name=$(echo "${repo_url}" | sed 's|https://git\.ociflab\.icu/||' | tr '/' '_')
local repo_path="${WORK_DIR}/${repo_name}"
if [[ -d "${repo_path}/.git" ]]; then
log " 更新: ${repo_url}"
if ! git -C "${repo_path}" pull --ff-only 2>&1; then
log " 更新失败: ${repo_url},尝试重新克隆..."
rm -rf "${repo_path}"
if ! git clone --depth 1 "${repo_url}" "${repo_path}" 2>&1; then
log " 重新克隆也失败: ${repo_url}"
return 1
fi
fi
else
log " 克隆: ${repo_url}"
rm -rf "${repo_path}"
if ! git clone --depth 1 "${repo_url}" "${repo_path}" 2>&1; then
log " 克隆失败: ${repo_url}"
return 1
fi
fi
return 0
}
backup_repos() {
local whitelist=("$@")
local total=${#whitelist[@]}
local failed=0
local failed_list=""
log "${total} 个仓库待备份"
for repo_url in "${whitelist[@]}"; do
[[ -z "${repo_url}" ]] && continue
if ! clone_or_pull_repo "${repo_url}"; then
failed=$((failed + 1))
failed_list="${failed_list}${repo_url}\n"
fi
done
# 检查错误率:超过三分之一则发送警告
if [[ ${total} -gt 0 ]]; then
local threshold=$((total / 3))
if [[ ${failed} -gt ${threshold} ]]; then
local warn_desp="备份失败 ${failed}/${total} 个仓库,超过三分之一。\n失败列表:\n${failed_list}"
send_warning "OCIFLAB备份异常 - ${failed}/${total} 仓库失败" "${warn_desp}"
fi
fi
log "备份完成: 成功 $((total - failed)) 个, 失败 ${failed}"
}
create_archive() {
log "正在压缩备份..."
mkdir -p "${ARCHIVE_DIR}"
local archive_name="ociflab-backup-${DATE_STAMP}.zip"
local archive_path="${ARCHIVE_DIR}/${archive_name}"
if [[ -d "${WORK_DIR}" ]] && [[ -n "$(ls -A "${WORK_DIR}" 2>/dev/null)" ]]; then
cd "${WORK_DIR}"
zip -r "${archive_path}" . -q
cd "${SCRIPT_DIR}"
log "压缩完成: ${archive_path}"
else
log "工作目录为空,跳过压缩"
fi
}
cleanup_old_archives() {
log "清理 ${RETENTION_DAYS} 天前的备份..."
find "${ARCHIVE_DIR}" -name "ociflab-backup-*.zip" -type f -mtime +${RETENTION_DAYS} -delete 2>/dev/null || true
log "清理完成"
}
persist_yesterday_whitelist() {
if [[ -f "${WHITELIST_CACHE}" ]]; then
cp "${WHITELIST_CACHE}" "${SCRIPT_DIR}/whitelist_cache.md.yesterday"
fi
}
# ---------- 主流程 ----------
main() {
log "========== OCIFLAB 备份开始 =========="
mkdir -p "${WORK_DIR}" "${ARCHIVE_DIR}"
# 1. 拉取白名单
if ! fetch_whitelist; then
log "无法获取白名单,退出"
send_warning "OCIFLAB备份失败" "无法拉取 whitelist.md 且无前一天缓存"
exit 1
fi
# 2. 解析仓库列表
mapfile -t repos < <(parse_whitelist)
if [[ ${#repos[@]} -eq 0 ]]; then
log "白名单为空,退出"
send_warning "OCIFLAB备份失败" "whitelist.md 中无有效仓库地址"
exit 1
fi
# 3. 克隆/更新仓库
backup_repos "${repos[@]}"
# 4. 压缩归档
create_archive
# 5. 清理旧备份
cleanup_old_archives
# 6. 保存今天的白名单供明天备用
persist_yesterday_whitelist
log "========== OCIFLAB 备份完成 =========="
}
main "$@"