rclone 批量上传下载脚本:重试 + 日志 + 分享链接

rclone 一条命令就能传单个文件到 Google Drive / OneDrive / S3 / OSS。但生产环境要批量重试日志结果链接——这就要写脚本。

前置:rclone 配好 remote

rclone config

跟着交互命令走,配好一个叫 gdrive 的 remote(可以是 Google Drive、S3、OSS、Backblaze 都行,脚本不区分)。

验证:

rclone lsd gdrive:

能列出根目录说明认证 OK。

批量上传脚本

upload.sh

#!/usr/bin/env bash
set -u

LOG_FILE="./upload.log"
RETRY=3
REMOTE_DIR="gdrive:backup"

for file in "$@"; do
  echo "上传: $file" | tee -a "$LOG_FILE"

  if [ ! -e "$file" ]; then
    echo "文件不存在: $file" | tee -a "$LOG_FILE"
    continue
  fi

  filename=$(basename "$file")
  remote_path="$REMOTE_DIR/$filename"

  count=0
  success=0
  while [ $count -lt $RETRY ]; do
    printf "第 %d 次尝试\n" $((count + 1)) | tee -a "$LOG_FILE"

    rclone copy "$file" "$REMOTE_DIR" \
      --stats 5s --stats-one-line \
      2>&1 | tee -a "$LOG_FILE"

    if [ ${PIPESTATUS[0]} -eq 0 ]; then
      success=1
      break
    fi

    count=$((count + 1))
    sleep 2
  done

  if [ $success -eq 1 ]; then
    echo "成功: $file" | tee -a "$LOG_FILE"

    # 生成分享链接(Google Drive / OneDrive 支持)
    link=$(rclone link "$remote_path" 2>/dev/null)
    if [ -n "$link" ]; then
      echo "分享链接: $link" | tee -a "$LOG_FILE"
    fi
  else
    echo "失败: $file" | tee -a "$LOG_FILE"
  fi
done

用法:

chmod +x upload.sh
./upload.sh a.zip b.tar.gz c.iso

关键点:

  • $@ — 传所有命令行参数
  • ${PIPESTATUS[0]} — 拿管道第一个命令的退出码(tee 会覆盖 $?,这里必须显式取 rclone 的)
  • --stats 5s --stats-one-line — 每 5 秒一行简洁进度,log 好看
  • rclone link — 生成分享链接,不支持的后端会返回空

对称的下载脚本

download.sh

#!/usr/bin/env bash
set -u

LOG_FILE="./download.log"
RETRY=3
REMOTE_DIR="gdrive:backup"

for remote_file in "$@"; do
  echo "下载: $remote_file" | tee -a "$LOG_FILE"

  remote_path="$REMOTE_DIR/$remote_file"

  count=0
  success=0
  while [ $count -lt $RETRY ]; do
    printf "第 %d 次尝试\n" $((count + 1)) | tee -a "$LOG_FILE"

    rclone copy "$remote_path" ./ \
      --stats 5s --stats-one-line \
      2>&1 | tee -a "$LOG_FILE"

    if [ ${PIPESTATUS[0]} -eq 0 ]; then
      success=1
      break
    fi

    count=$((count + 1))
    sleep 2
  done

  if [ $success -eq 1 ]; then
    echo "成功: $remote_file" | tee -a "$LOG_FILE"
  else
    echo "失败: $remote_file" | tee -a "$LOG_FILE"
  fi
done

用法:

./download.sh a.zip b.tar.gz

加分项

并发上传rclone copy 支持 --transfers 参数,一次传多个文件:

rclone copy "$file" "$REMOTE_DIR" --transfers 8 --checkers 16

限速(别把家里带宽打满):

rclone copy "$file" "$REMOTE_DIR" --bwlimit 10M

校验完整性

rclone check "$file" "$REMOTE_DIR/$filename"

断点续传rclone copy 天生支持,直接重跑同一命令即可。已经完成的文件会跳过。

多线程分块(大文件):

rclone copy "$file" "$REMOTE_DIR" \
  --multi-thread-streams 4 \
  --multi-thread-cutoff 100M

挂 cron 定时备份

0 3 * * * /home/me/upload.sh /var/backups/db-*.sql.gz >> /var/log/backup.log 2>&1

配合 find 只传新文件:

find /var/backups -mmin -60 -name "*.sql.gz" -exec /home/me/upload.sh {} +

一句话总结

rclone copy + Bash 循环 + ${PIPESTATUS[0]} 判成功 = 稳的批量传输脚本。加个 --stats 看进度、rclone link 抓分享链接就够生产用。