Rclone 备份本地到云盘

1008 字
5 分钟
Rclone 备份本地到云盘

概述#

本方案提供一个可直接运行的 Bash 脚本,用于将本地目录与远端网盘(示例:通过 Openlist 暴露的云盘 WebDAV)进行高可靠同步。脚本内置带宽时间表、模拟运行、安全的日志权限与日志数量上限清理,并针对 WebDAV 链路加入了缓冲、重试与限流优化。

快速开始#

安装并配置 rclone#

Terminal window
sudo apt-get update && sudo apt-get install -y rclone
rclone version
rclone config # 建立并测试名为 myremote 的 WebDAV 远端

创建脚本并设置权限#

Terminal window
chmod +x ./rclone_sync.sh

Rclone 脚本#

#!/bin/bash
set -euo pipefail
umask 022
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
# ===== 固定参数开始(按需修改)=====
LOCAL_DIR="/path/to/source" # 本地要同步的目录(源)
REMOTE_PATH="myremote:/path/in/remote" # 远端路径:remote 名称:目标子路径(目的地)
BW_SCHEDULE="00:00,12M 08:00,5M 23:00,12M" # 带宽时间表(本地时间循环):08:00–23:00 5M/s,其余 12M/s
TRANSFERS=4 # 并发文件传输数,建议 3–4(适中减轻限速/429)
CHECKERS=8 # 校验/列目录并发数,建议为 TRANSFERS 的 1.5–2 倍
LOG_DIR="/path/to/logs/rclone_sync" # 日志目录(建议 SSD/缓存盘)
SIMULATE=true # 模拟运行:true/false(仅打印不改动)
MAX_LOG_FILES=30 # 日志数量上限;0 表示不限制
LOG_FILE_OWNER="nobody" # 日志文件属主(便于 SMB/Unraid 客户端读取);留空不更改
LOG_FILE_GROUP="users" # 日志文件属组;留空不更改
BUFFER_SIZE="32M" # 传输缓冲区:常用 16M 或 32M(更大更占内存)
RETRIES=6 # 高层重试次数(处理 HTTP 429/网络抖动)
RETRIES_SLEEP="10s" # 高层重试间隔
LOW_LEVEL_RETRIES=20 # 底层分片/连接重试次数
TIMEOUT="5m" # 单次 I/O 超时(读写)
CONN_TIMEOUT="20s" # 连接建立超时
TPSLIMIT=8 # 每秒请求上限(防 429)
TPSLIMIT_BURST=16 # 瞬时突发上限
MODIFY_WINDOW="2s" # 修改时间容差;若仍异常可改用 --size-only
# ===== 固定参数结束 =====
mkdir -p "${LOG_DIR}"
if ! command -v rclone >/dev/null 2>&1; then
echo "[ERROR] 未找到 rclone,请先安装与配置 rclone。" >&2
exit 1
fi
:
if [[ ! -d "${LOCAL_DIR}" ]]; then
echo "[ERROR] 本地目录不存在:${LOCAL_DIR}" >&2
exit 3
fi
# 带宽时间表(本地时间,按日循环)和性能参数已固定在上方
TIMESTAMP="$(date +"%Y%m%d_%H%M%S")"
LOG_FILE="${LOG_DIR}/rclone_sync_${TIMESTAMP}.log"
echo "[INFO] 开始同步"
echo "[INFO] 本地: ${LOCAL_DIR}"
echo "[INFO] 远端: ${REMOTE_PATH}"
echo "[INFO] 带宽时间表: ${BW_SCHEDULE}"
echo "[INFO] 日志: ${LOG_FILE}"
if [[ "${SIMULATE}" == "true" ]]; then
echo "[INFO] 模拟运行: 已开启 (--dry-run)"
else
echo "[INFO] 模拟运行: 关闭"
fi
# 说明:
# --delete-after 默认行为由 sync 决定(保持远端与本地一致),如需先传后删可显式加此项
# --stats-one-line 更简洁的进度输出
# --log-level INFO 常用日志级别(DEBUG 更详细)
# 如使用特定后端(如 drive/s3),可追加相应优化参数(例如 --drive-chunk-size 等)。
# 预创建日志并设置权限/属主(若配置了 LOG_FILE_OWNER/GROUP 且系统存在)
touch "${LOG_FILE}" || true
chmod 644 "${LOG_FILE}" || true
chmod 755 "${LOG_DIR}" || true
if id -u "${LOG_FILE_OWNER}" >/dev/null 2>&1 && getent group "${LOG_FILE_GROUP}" >/dev/null 2>&1; then
chown "${LOG_FILE_OWNER}:${LOG_FILE_GROUP}" "${LOG_FILE}" || true
fi
CMD=(
rclone sync
"${LOCAL_DIR}" "${REMOTE_PATH}"
--bwlimit "${BW_SCHEDULE}"
--transfers "${TRANSFERS}"
--checkers "${CHECKERS}"
--log-file "${LOG_FILE}"
--log-level INFO
--stats 30s
--stats-one-line
--buffer-size "${BUFFER_SIZE}"
--retries "${RETRIES}"
--retries-sleep "${RETRIES_SLEEP}"
--low-level-retries "${LOW_LEVEL_RETRIES}"
--timeout "${TIMEOUT}"
--contimeout "${CONN_TIMEOUT}"
--tpslimit "${TPSLIMIT}"
--tpslimit-burst "${TPSLIMIT_BURST}"
--modify-window "${MODIFY_WINDOW}"
)
if [[ "${SIMULATE}" == "true" ]]; then
CMD+=(--dry-run)
fi
"${CMD[@]}"
EXIT_CODE=$?
if [[ ${EXIT_CODE} -eq 0 ]]; then
echo "[INFO] 同步完成"
else
echo "[ERROR] 同步失败,退出码:${EXIT_CODE}" >&2
fi
# 按数量上限清理旧日志
if [[ -n "${LOG_DIR}" && -d "${LOG_DIR}" && ${MAX_LOG_FILES} -gt 0 ]]; then
# 按时间倒序列出匹配日志文件
mapfile -t _log_files < <(ls -1t "${LOG_DIR}"/rclone_sync_*.log 2>/dev/null || true)
total_logs=${#_log_files[@]}
if [[ ${total_logs} -gt ${MAX_LOG_FILES} ]]; then
to_delete=$(( total_logs - MAX_LOG_FILES ))
echo "[INFO] 日志数量 ${total_logs} 超过上限 ${MAX_LOG_FILES},将删除最旧的 ${to_delete} 个日志"
# 从时间倒序数组的尾部开始删除(即最旧)
for (( i=total_logs-1; i>=MAX_LOG_FILES; i-- )); do
rm -f -- "${_log_files[$i]}" || true
done
fi
fi
exit ${EXIT_CODE}

编辑脚本顶部参数,至少确认:#

  • LOCAL_DIR:本地源目录
  • REMOTE_PATH:目标远端(remote:子路径)
  • LOG_DIR:日志目录(建议本地 SSD/缓存盘)
  • SIMULATE:首次运行建议设为 true(仅预演不改动)

执行模拟#

Terminal window
./rclone_sync.sh # 当 SIMULATE=true 时,仅打印将要执行的操作

正式执行#

将脚本内 SIMULATE=false 后再次运行:

Terminal window
./rclone_sync.sh

crontab(每天 2:30 执行一次):

Terminal window
crontab -e
30 2 * * * /bin/bash /path/to/rclone_sync.sh >> /dev/null 2>&1
Rclone 备份本地到云盘
https://lunary.cc/posts/rclone-备份本地到云盘/
作者
鹤望兰
发布于
2025-10-14
许可协议
CC BY-NC-SA 4.0