Bash + rclone · OneDrive ↔ Google Drive · 开源操作指南

使用 Bash 和 rclone 执行仅复制的云端传输

rclone 已经能够处理云端分页、重试、可恢复传输和服务商哈希值。工程任务是将这些基础能力封装为一套默认拒绝且可感知容量的操作流程。

更新日期 ; 20 分钟读完.

简短回答

对于大型或无人值守的迁移,FileArk 是更简单的托管式选择:它在线运行传输,已针对数 TB 工作负载进行测试,并会在完成前检查每项结果。对于希望通过 shell 控制数据传输路径的操作者,这个采用 MIT 许可证的 Bash 封装程序会通过本地暂存按限定批次进行复制,对两个传输阶段逐字节验证,并且绝不删除源文件。

为何封装 rclone,而不是重新构建每个云服务商客户端

rclone 为 shell 工作流提供了成熟的云服务商抽象层、OAuth 配置、分页、重试机制、可恢复传输、并发控制、清单命令和验证命令。因此,这个封装程序可以专注于迁移过程中的不变约束:仅复制命令、有界暂存、容量预留、确定性文件列表和持久化进度。

但这并不意味着任务会自动完成。操作者仍需负责远程端配置、令牌安全、网络可用性、进程监管、本地磁盘、日志、服务商限制、失败对象审查和目标端验收。对于希望以托管式在线工作流运行该流程,而不是在自己的工作站或服务器上操作的用户,FileArk 正是为此而设计。

脚本明确禁止调用 rclone move、sync、delete、purge 或 rmdirs。它使用 lsf 和 about 进行探查,对两个传输阶段使用 copy,并使用 check --download 进行全字节验证。唯一会移除的是本地暂存目录中已经过验证的文件。

下载 Bash 版本和 MIT 许可证

下载 Bash 和 rclone 传输程序
一个仅复制的封装程序,提供批次限制、本地和目标端空间预留、全字节验证、检查点、重试控制以及无需网络的演示。
fileark-cloud-transfer.sh · Bash 4+ · rclone · jq · MIT 许可证

下载 MIT 许可证
适用于两个 FileArk 手动传输脚本的许可声明。
LICENSE-fileark-cloud-transfer.txt · MIT · 纯文本

运行无需联网的操作演示

终端正在以演示模式运行 FileArk Bash 和 rclone 云传输脚本
该演示展示一个大小受限的批次通过两道验证边界。它不会检查 rclone 配置、连接云服务或写入远程数据。

即使尚未安装 rclone 或 jq,也可以安全运行演示,因为参数解析会在依赖项检查之前退出。输出会列出禁止执行的破坏性操作、显示两项容量预留,并在最后给出源文件删除数量。

检查下载内容并进行冒烟测试
chmod +x fileark-cloud-transfer.sh
bash -n fileark-cloud-transfer.sh
./fileark-cloud-transfer.sh --demo
./fileark-cloud-transfer.sh --help

安装并配置操作所需的依赖项

请按照官方说明安装最新版本的 rclone,并通过操作系统的软件包管理器安装 jq。该封装脚本使用了严格的错误处理和现代条件表达式,因此需要 Bash 4 或更高版本。

运行 rclone config 并创建两个名称彼此独立的远程端,例如 onedrive: 和 gdrive:。如果政策或速率限制要求使用专用 OAuth 应用,请输入您自己的服务商客户端 ID 和密钥。rclone 会将 OAuth 令牌存储在其配置文件中;请通过严格的权限保护该文件,切勿将其与脚本打包在一起。

运行封装程序前,请使用只读列表命令和配额命令确认每个远程端。当范围仅涵盖一个子树时,请使用 onedrive:Department/Archive 之类的路径。

配置并检查两个远程端
rclone version
rclone config
rclone lsd onedrive:
rclone lsd gdrive:
rclone about onedrive: --json | jq
rclone about gdrive: --json | jq

在传输数据前冻结一份确定性清单

该封装程序以递归方式使用 rclone lsf,明确指定制表符作为分隔符并采用 sp 格式,从而生成“大小在前、路径在后”的输出。它会验证每个大小是否为数字、每条路径是否为相对路径,然后排除已存在于验证检查点中的路径。

Bash 版本会拒绝包含制表符、回车符或换行符的文件名,因为以换行符分隔的 --files-from-raw 列表无法无歧义地表示这些名称。如果存在此类名称,请使用 Python 版本或专门设计的清单格式。

路径检查点特意采用简单且易于检查的设计。它假定源路径在运行期间保持不变。如条件允许,请冻结对源端的写入;如果预计会有并发更改,则应重新生成清单并进行核对。

封装程序使用的清单基础命令
rclone lsf "$SOURCE" \
  --recursive \
  --files-only \
  --format "sp" \
  --separator 
    
  

\t' > "$inventory"

在批次占用预留空间前中止

本地可用字节数通过暂存文件系统上的 df 获取。目标端可用字节数来自 rclone about --json:如果返回 free,脚本就使用该值;否则用 total 减去 used。脚本会在开始处理前检查待传输数据的总字节数,并在每个批次开始前再次检查本地和目标端容量。

某些提供商或账户类型不会通过 rclone 公布有限的配额。封装脚本会输出此限制,并在提供商的限制机制下继续运行。应将这种情况视为一项监控要求,而不是空间充足的证明。

批次限制并不是单个对象的硬性大小上限。大于所配置批次大小的单个文件可以独立组成一个批次,因此本地可用空间必须足以容纳最大文件并满足预留要求。在 rclone 版本中,完整目标验证会从目标端读取字节,但不会在本地保留第二份副本。

验证本地暂存边界的两侧

每个批次都会经过两个相互独立的传输阶段。首先,rclone 使用 --ignore-existing 将选定的源路径复制到本地暂存区,然后由 check --download 读取两端数据并比较实际内容。其次,rclone 将这些暂存路径复制到目标端,并重复执行相同的全字节检查。

--ignore-existing 可确保中断后的重新运行不会造成破坏:已有对象不会被覆盖。路径只有通过验证后才能写入检查点。如果目标端的已有对象内容不同,rclone check 将失败,Bash 的严格错误处理会停止运行。

使用 --download 速度较慢,并会消耗提供商的出站流量和读取操作,但它避免了仅依赖两个提供商是否支持同一种哈希算法。该命令不会修改任一端。

两个复制与验证阶段
rclone copy "$SOURCE" "$STAGING_DIR" \
  --files-from-raw "$batch_list" \
  --ignore-existing --retries 6 --low-level-retries 20

rclone check "$SOURCE" "$STAGING_DIR" \
  --files-from-raw "$batch_list" --one-way --download

rclone copy "$STAGING_DIR" "$DESTINATION_ROOT" \
  --files-from-raw "$batch_list" \
  --ignore-existing --retries 6 --low-level-retries 20

rclone check "$STAGING_DIR" "$DESTINATION_ROOT" \
  --files-from-raw "$batch_list" --one-way --download

使用受限暂存空间执行从 OneDrive 到 Google Drive 的传输

本示例会在本地磁盘保留 15 GiB 空间不使用,在 Google Drive 保留 10 GiB 可用空间,将常规批次限制为 8 GiB 或 200 个文件,并使用四个并发传输。目标内容会写入一个以日期命名的新文件夹。

请先使用 --dry-run。它会执行源数据清点和目标配额预检,但不会下载或上传。封装脚本会输出所有待传输数据的总字节数;在执行第一个实际批次前,应将其与迁移范围进行核对。

先预检,再执行相同范围的传输
./fileark-cloud-transfer.sh \
  --source onedrive: \
  --destination gdrive: \
  --destination-folder "OneDrive archive 2026-07-25" \
  --staging-dir /srv/fileark-staging \
  --state-file ./onedrive-to-google-verified.txt \
  --batch-gib 8 \
  --batch-files 200 \
  --local-reserve-gib 15 \
  --destination-reserve-gib 10 \
  --transfers 4 \
  --checkers 8 \
  --dry-run

# Remove only --dry-run after reviewing the preflight.

反转传输方向,但不复用状态

由于远程适配器由 rclone 提供,该封装程序不依赖特定云服务商。调换远程端参数即可将 Google Drive 复制到 OneDrive,并为该次运行指定新的目标文件夹、暂存路径和检查点文件。

Google 原生的文档、表格、幻灯片及其他虚拟格式需要配置 rclone 导出并仔细检查。请使用测试集确认导出后的扩展名和转换行为。通过 shell 复制无法保留 Google 协作历史记录、快捷方式、权限或 Microsoft 特有的元数据。

从 Google Drive 迁移到 OneDrive
./fileark-cloud-transfer.sh \
  --source gdrive: \
  --destination onedrive: \
  --destination-folder "Google archive 2026-07-25" \
  --staging-dir /srv/google-staging \
  --state-file ./google-to-onedrive-verified.txt \
  --batch-gib 8 \
  --local-reserve-gib 15

仅在目标端验证通过后写入检查点

目标端检查成功退出后,封装程序会将每条相对路径追加到纯文本检查点中。随后,它会从本地暂存区删除相应文件,并移除本地空目录。源远程端不会受到任何改动。

检查点在运行期间仅追加内容,并且可以使用标准工具轻松审计。请将其与命令行、rclone 版本、配置指纹、清单、日志、时间戳和验收记录一并保存。除非已独立验证目标文件,否则不要通过编辑检查点来掩盖失败。

仅记录路径的检查点无法检测路径未变但内容已更改的源对象。对于可变数据集,请暂停写入,单独记录提供商 ID 和修改元数据,或使用 Python 版本中更严格的 ID 与大小检查点。对于受监管或涉及协作的迁移,请使用具有明确变更控制的托管工作流。

将每次非零退出都视为尚未解决的批次

  • 当命令、管道或未设置的变量导致错误时,严格模式会退出;临时清单目录会自动删除。
  • rclone 会重试暂时性传输故障,但持续存在的权限、配额、网络、冲突或完整性错误会停止该批次。
  • 尚未写入检查点的暂存文件会保留以供检查;使用相同参数重新运行时,会先应用 --ignore-existing,再检查这些文件的字节内容。
  • 绝不会覆盖目标端内容不同的文件。请解决冲突,或选择一个干净的目标根目录。
  • 不要将失败的复制改为 rclone sync 或 move。这些命令具有不同的删除语义。
  • 在目标端人工验收完成之前,请保留日志和检查点。

保护作为数据平面的主机

暂存主机会临时存有可读取的源数据副本和 OAuth 刷新令牌。请启用全盘加密,设置严格的文件权限,使用专用操作系统账户,及时修补依赖项,限制管理员访问,并制定加密备份策略,避免意外保留暂存内容。

避免在命令行中使用密钥,因为进程列表和 shell 历史记录可能会将其暴露。rclone 的受保护配置可以隐藏静态存储的令牌,但不能替代主机安全措施。迁移验收完成后,请按照您的保留政策移除令牌材料和暂存残留内容。

监控云服务商审计日志、网络出站流量、磁盘健康状况、inode 可用量、进程状态和 rclone 输出。仅让终端保持打开并不等于进程监管;请使用获准的服务管理器或终端复用器,并确保持久保存日志。

用证据完成迁移验收,而非仅凭命令显示成功

  • 将冻结的清单、确切命令、脚本校验和、rclone 版本、远程端配置指纹和已验证的检查点归档保存。
  • 按文件夹核对文件数量和已知字节数,不要只核对整个云盘的总计。
  • 根据风险抽样打开不同类型的文档,包括大文件、小文件、旧文件、新文件、使用 Unicode 名称的文件、深层嵌套文件、归档文件和转换后的文档。
  • 使用具有代表性的用户账户测试目标端访问权限,并单独重新建立所需的共享设置。
  • 检查被跳过的软件包、快捷方式、链接、原生文档、冲突和服务商警告。
  • 保留一段源数据重叠期,并在后续做出任何保留或删除决定前,获得所有者的明确认可。

常见问题

为什么 Bash 脚本使用 rclone copy 而不是 sync?

复制不会删除源对象,也不会移除目标端中源端不存在的对象。同步具有不同的核对与删除语义,因此本工作流有意将其排除在外。

rclone check --download 会更改任一云端的内容吗?

不会。它只读取并比较文件内容。脚本会在每一段复制完成后使用该命令,因此只有当目标端字节与暂存字节一致时,才会为相应路径设置检查点。

如果目标端已存在文件,会发生什么?

复制使用 --ignore-existing,随后进行全字节验证。内容相同的对象可以通过验证;对象内容不同则会导致检查失败。脚本绝不会覆盖发生冲突的对象。

脚本能否处理大于单个批次的文件?

可以。单个超大文件会单独成为一个批次。暂存文件系统必须有足够空间容纳该文件及配置的本地预留空间。

这会迁移权限、版本或云原生协作数据吗?

不会。它通过 rclone 复制文件内容和路径。访问控制、版本、标签、评论、快捷方式、链接、保留规则以及提供商原生行为都需要单独规划和验证。

本指南使用的官方资料

阅读指南