plot37 · 代码 4 · 图 0 · 笔记 1 · 代码库专题
BaiduPCS-Go网盘备份
代码库整理的专题,README 见原始目录。
BaiduPCS-Go网盘备份(自动生成占位图)
图源:(自动生成占位图)
分析代码
4 个源码文件,按目录顺序;本机绝对路径已替换为 ~。 代码可复制,但需要按自己的数据改路径与参数。
01_install_baidupcs_go.sh
#!/usr/bin/env bash
# ============================================================
# 5.3 BaiduPCS-Go 安装 / 升级脚本
# 用法: ./01_install_baidupcs_go.sh [版本号]
# 例: ./01_install_baidupcs_go.sh # 默认装 v4.0.2
# ./01_install_baidupcs_go.sh v4.0.2 # 指定版本
# 说明: 装到 ~/.local/bin (无需 sudo), 配置目录 ~/.config/BaiduPCS-Go
# 仓库: https://github.com/qjfoidnh/BaiduPCS-Go
# ============================================================
set -euo pipefail
VERSION="${1:-v4.0.2}"
REPO="qjfoidnh/BaiduPCS-Go"
BIN_DIR="$HOME/.local/bin"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
# ---------- 1. 探测架构 ----------
case "$(uname -m)" in
x86_64) ARCH="amd64" ;;
aarch64|arm64) ARCH="arm64" ;;
armv7l) ARCH="arm" ;;
i386|i686) ARCH="386" ;;
*) echo "❌ 不支持的架构: $(uname -m)"; exit 1 ;;
esac
case "$(uname -s)" in
Linux) OS="linux" ;;
Darwin) OS="darwin" ;;
*) echo "❌ 不支持的系统: $(uname -s)"; exit 1 ;;
esac
echo "🔍 平台: ${OS}/${ARCH} 版本: ${VERSION}"
# ---------- 2. 下载 ----------
PKG="BaiduPCS-Go-${VERSION}-${OS}-${ARCH}"
URL="https://github.com/${REPO}/releases/download/${VERSION}/${PKG}.zip"
echo "⬇️ 下载: $URL"
curl -fL --retry 3 --max-time 600 -o "$TMP_DIR/pkg.zip" "$URL"
# ---------- 3. 解压 + 安装 ----------
unzip -oq "$TMP_DIR/pkg.zip" -d "$TMP_DIR"
SRC="$(find "$TMP_DIR" -type f -name "BaiduPCS-Go" -perm -u+x | head -1)"
if [ -z "$SRC" ]; then
SRC="$(find "$TMP_DIR" -type f -name "BaiduPCS-Go" | head -1)"
fi
[ -n "$SRC" ] || { echo "❌ 解压后未找到 BaiduPCS-Go 二进制"; exit 1; }
mkdir -p "$BIN_DIR"
install -m 755 "$SRC" "$BIN_DIR/BaiduPCS-Go"
echo "✅ 已安装到: $BIN_DIR/BaiduPCS-Go"
# ---------- 4. 验证 ----------
export PATH="$BIN_DIR:$PATH"
if ! command -v BaiduPCS-Go >/dev/null 2>&1; then
echo "⚠️ $BIN_DIR 不在 PATH 中, 请把下面一行加进 ~/.bashrc:"
echo " export PATH=\"\$HOME/.local/bin:\$PATH\""
else
echo "🎉 $(BaiduPCS-Go --version)"
fi
echo
echo "下一步: 登录百度账号"
echo " BaiduPCS-Go login # 交互式粘贴 BDUSS"
echo " BaiduPCS-Go who # 确认登录状态"
02_pan_backup.sh
#!/usr/bin/env bash
# ============================================================
# 5.3 备份: 本地 → 百度网盘 (增量上传)
# 用法:
# ./02_pan_backup.sh # 默认备份 04_数据下载与备份 → 网盘 /hz_代码教程备份/04_数据下载与备份
# ./02_pan_backup.sh <本地目录> <网盘目录> # 自定义
# ./02_pan_backup.sh --list # 只看网盘上已有什么
# 特性: upload_policy=rsync → 只传新增/变化的文件, 同名同大小自动跳过
# ============================================================
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
PAN_DEFAULT="/hz_代码教程备份/04_数据下载与备份"
LOCAL_DEFAULT="$(cd "$HERE/.." && pwd)" # = 04_数据下载与备份
# ---------- 0. 环境检查 ----------
command -v BaiduPCS-Go >/dev/null 2>&1 || {
echo "❌ 未找到 BaiduPCS-Go, 请先跑 ./01_install_baidupcs_go.sh"; exit 1; }
if ! BaiduPCS-Go who 2>/dev/null | grep -q "uid: [1-9]"; then
echo "❌ 尚未登录百度账号, 请先执行: BaiduPCS-Go login"; exit 1
fi
# ---------- 1. 参数 ----------
if [ "${1:-}" = "--list" ]; then
echo "📂 网盘 $PAN_DEFAULT 下已备份的内容:"
BaiduPCS-Go ls "$PAN_DEFAULT" 2>&1 || echo " (目录尚不存在)"
exit 0
fi
LOCAL="${1:-$LOCAL_DEFAULT}"
PAN_DEST="${2:-$PAN_DEFAULT}"
LOCAL="$(cd "$LOCAL" && pwd)" # 转绝对路径, 校验存在
echo "============================================"
echo " 本地源 : $LOCAL"
echo " 网盘目标: $PAN_DEST"
echo " 上传策略: $(BaiduPCS-Go config 2>/dev/null | awk '/upload_policy/{print $2}') (rsync=增量)"
echo "============================================"
# ---------- 2. 确认网盘目标目录存在 ----------
if ! BaiduPCS-Go meta "$PAN_DEST" >/dev/null 2>&1; then
echo "📁 网盘目录不存在, 自动创建: $PAN_DEST"
BaiduPCS-Go mkdir "$PAN_DEST" >/dev/null
fi
# ---------- 3. 逐个一级子项上传, 跳过本地暂存目录 ----------
# data/ 是网盘下载落点, 内容本来就在网盘上, 不回传
SKIP_RE='(^|/)(data|\.git|_downloads)$'
shopt -s nullglob
ITEMS=()
for p in "$LOCAL"/*; do
name="$(basename "$p")"
if [[ "$name" =~ $SKIP_RE ]]; then
echo "⏭️ 跳过: $name (本地暂存/下载落点)"
continue
fi
ITEMS+=("$p")
done
shopt -u nullglob
if [ ${#ITEMS[@]} -eq 0 ]; then
echo "⚠️ 没有可备份的内容 (全部被跳过)"; exit 0
fi
# ---------- 4. 执行上传 ----------
echo "⬆️ 开始上传 ${#ITEMS[@]} 个条目..."
# -l 2 同时上传 2 个文件 (非 SVIP 单个文件并发受限, 多文件并行更划算)
# -p 4 单文件 4 线程
# --policy rsync 跳过大小未变化的文件, 其余覆盖
BaiduPCS-Go upload -l 2 -p 4 --policy rsync "${ITEMS[@]}" "$PAN_DEST"
echo
echo "✅ 备份完成。核对网盘内容:"
BaiduPCS-Go ls "$PAN_DEST"
03_pan_restore.sh
#!/usr/bin/env bash
# ============================================================
# 5.3 恢复: 百度网盘 → 本地 (下载)
# 用法:
# ./03_pan_restore.sh <网盘路径> [本地目录]
# 网盘路径缺省 = /hz_代码教程备份/04_数据下载与备份
# 本地目录缺省 = ./data/
# ./03_pan_restore.sh --list [网盘路径] # 只列出网盘内容
# 特性: 支持断点续传 / 多线程 / 下载后自动 md5 校验 / 重名自动跳过
# ============================================================
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
PAN_DEFAULT="/hz_代码教程备份/04_数据下载与备份"
LOCAL_DIR="$HERE/data"
command -v BaiduPCS-Go >/dev/null 2>&1 || {
echo "❌ 未找到 BaiduPCS-Go, 请先跑 ./01_install_baidupcs_go.sh"; exit 1; }
if ! BaiduPCS-Go who 2>/dev/null | grep -q "uid: [1-9]"; then
echo "❌ 尚未登录百度账号, 请先执行: BaiduPCS-Go login"; exit 1
fi
# ---------- 1. 列目录模式 ----------
if [ "${1:-}" = "--list" ]; then
BaiduPCS-Go ls "${2:-$PAN_DEFAULT}"
exit 0
fi
# ---------- 2. 参数 ----------
PAN_SRC="${1:-$PAN_DEFAULT}"
[ -n "${2:-}" ] && LOCAL_DIR="$2"
mkdir -p "$LOCAL_DIR"
LOCAL_DIR="$(cd "$LOCAL_DIR" && pwd)"
echo "============================================"
echo " 网盘源 : $PAN_SRC"
echo " 保存到 : $LOCAL_DIR"
echo "============================================"
# ---------- 3. 下载 ----------
# --saveto 直接落到指定目录 (否则默认写 savedir)
# -p 4 单文件 4 线程 -l 2 同时下载 2 个文件
# 不加 --ow → 重名文件自动跳过 (续传场景安全)
echo "⬇️ 开始下载..."
BaiduPCS-Go download -p 4 -l 2 --saveto "$LOCAL_DIR" "$PAN_SRC"
echo
echo "✅ 下载完成。本地结果:"
ls -lh "$LOCAL_DIR"
04_demo_双向验证.sh
#!/usr/bin/env bash
# ============================================================
# 5.3 Demo: 小文件双向同步验证 (上传 → 网盘 → 下载回来 → md5 比对)
# 用法: ./04_demo_双向验证.sh
# 目的: 用几 KB 的测试文件跑通整条链路, 确认备份/恢复真的可用
# 注意: 不用网盘记录的 md5 做判据 —— 分片上传可能写错服务器端 md5,
# 唯一可信的判据是"下载回来的文件"与"上传前的原文件"逐字节一致。
# ============================================================
set -euo pipefail
HERE="$(cd "$(dirname "$0")" && pwd)"
PAN_DEMO="/hz_代码教程备份/_demo_双向验证"
WORK="$HERE/data/_demo_verify"
STAMP="$(date +%Y%m%d_%H%M%S)"
FNAME="demo_${STAMP}.txt"
command -v BaiduPCS-Go >/dev/null 2>&1 || {
echo "❌ 未找到 BaiduPCS-Go, 请先跑 ./01_install_baidupcs_go.sh"; exit 1; }
if ! BaiduPCS-Go who 2>/dev/null | grep -q "uid: [1-9]"; then
echo "❌ 尚未登录百度账号, 请先执行: BaiduPCS-Go login"; exit 1
fi
rm -rf "$WORK"; mkdir -p "$WORK/up" "$WORK/down"
echo "============================================"
echo " 步骤 1/5 造测试文件"
echo "============================================"
{
echo "BaiduPCS-Go 双向同步验证"
echo "生成时间: $STAMP"
echo "主机: $(hostname)"
echo "随机载荷: $(head -c 32 /dev/urandom | base64)"
} > "$WORK/up/$FNAME"
MD5_SRC="$(md5sum "$WORK/up/$FNAME" | awk '{print $1}')"
SIZE_SRC="$(stat -c%s "$WORK/up/$FNAME")"
echo " 文件: $FNAME (${SIZE_SRC} 字节)"
echo " md5 : $MD5_SRC"
echo
echo "============================================"
echo " 步骤 2/5 上传 → $PAN_DEMO"
echo "============================================"
BaiduPCS-Go meta "$PAN_DEMO" >/dev/null 2>&1 || BaiduPCS-Go mkdir "$PAN_DEMO" >/dev/null
BaiduPCS-Go upload --policy overwrite "$WORK/up/$FNAME" "$PAN_DEMO"
echo
echo "============================================"
echo " 步骤 3/5 确认网盘上确实存在"
echo "============================================"
BaiduPCS-Go ls "$PAN_DEMO"
BaiduPCS-Go meta "$PAN_DEMO/$FNAME" 2>&1 | grep -iE "文件名|大小|size|md5" || true
echo
echo "============================================"
echo " 步骤 4/5 下载回来 → $WORK/down"
echo "============================================"
BaiduPCS-Go download --save --ow "$PAN_DEMO/$FNAME" 2>&1 || \
BaiduPCS-Go download --saveto "$WORK/down" --ow "$PAN_DEMO/$FNAME"
# 定位下载到的文件 (--save 落当前目录, --saveto 落指定目录)
DL="$(find "$WORK/down" "$HERE" -maxdepth 2 -type f -name "$FNAME" -newermt '-5 minutes' 2>/dev/null | head -1)"
[ -n "$DL" ] || DL="$WORK/down/$FNAME"
[ -f "$DL" ] || { echo "❌ 未找到下载回来的文件"; exit 1; }
echo
echo "============================================"
echo " 步骤 5/5 逐字节比对"
echo "============================================"
MD5_DL="$(md5sum "$DL" | awk '{print $1}')"
SIZE_DL="$(stat -c%s "$DL")"
echo " 原始 : ${SIZE_SRC} 字节 md5=$MD5_SRC"
echo " 下载回: ${SIZE_DL} 字节 md5=$MD5_DL"
echo
if [ "$MD5_SRC" = "$MD5_DL" ] && [ "$SIZE_SRC" = "$SIZE_DL" ]; then
echo "🎉 双向验证通过 —— 上传与下载链路均可用, 文件内容完全一致"
echo
echo "接下来可以正式备份了:"
echo " ./02_pan_backup.sh # 备份 04_数据下载与备份 → 网盘"
echo " ./03_pan_restore.sh --list # 查看网盘上有什么"
else
echo "❌ 验证失败 —— 两端不一致, 请勿用于正式备份"
exit 1
fi