首页
/ rclone check 命令完全指南:云端与本地文件一致性校验的原理与实战

rclone check 命令完全指南:云端与本地文件一致性校验的原理与实战

2026-09-07 10:26:48作者:郜逊炳

rclone check 是 rclone 提供的“只读校验”命令,用于对比源与目标两端目录中的文件在大小与哈希上是否一致,并输出一份差异报告;它不会对两端做任何增删改。本指南以 docs/content/commands/rclone_check.md 为骨架,结合 cmd/check/fs/operations/ 的源码实现,帮你彻底掌握:何时该用 check--size-only / --download / --checkfile / --one-way 各解决什么问题,以及 --combined--differ 等报告选项如何配合脚本自动化做“云端数据巡检”。读完你将能够把 rclone 的校验能力落地到备份验证、迁移后核对、定时数据完整性扫描等实战场景。

命令概览与基本用法

rclone check 的职责一句话即可概括:检查源端与目标端的文件是否匹配。它在两棵目录树上同时遍历同名文件,逐一对比大小与哈希(MD5 或 SHA1 等),把不匹配的文件记录到报告中;整个过程不会修改源或目标上的任何文件。

命令格式如下:

rclone check source:path dest:path [flags]

最基本的用法是给出两个远程(或本地路径与远程的组合):

# 对比本地目录与云端远程目录
rclone check /home/user/backup remote:backup

# 对比两个不同云存储上的目录
rclone check gdrive:docs s3:docs-archive

运行结束后,rclone 会在日志里汇总统计信息,例如“发现了 N 处差异”“N 个匹配文件”等。核心入口定义在 cmd/check/check.goRunE 先通过 cmd.CheckArgs(2, 2, ...) 强制要求恰好两个位置参数(source:pathdest:path),随后在闭包中调用底层实现 operations.Check

在继续之前,先完整列出本命令专属的选项表(对应文档 Options 小节):

  -C, --checkfile string        Treat source:path as a SUM file with hashes of given type
      --combined string         Make a combined report of changes to this file
      --differ string           Report all non-matching files to this file
      --download                Check by downloading rather than with hash
      --error string            Report all files with errors (hashing or reading) to this file
  -h, --help                    help for check
      --match string            Report all matching files to this file
      --missing-on-dst string   Report all files missing from the destination to this file
      --missing-on-src string   Report all files missing from the source to this file
      --one-way                 Check one way only, source files must exist on remote

这些专属 flag 的绑定与默认值可在 cmd/check/check.go 中看到:例如 --download--one-way 为布尔开关,--combined--differ--match 等则接收一个“输出文件名”字符串参数(值为 - 时表示写到 stdout,这一点后文会细讲)。

校验原理:大小 + 公共哈希的双重对比

check 的默认判断流程是“先比大小、再比哈希”,逐层递进:

  1. 大小对比:对于两端都存在的同名文件,若大小不一致,直接判定“sizes differ”(差异)。底层逻辑在 fs/operations/operations.gosizeDiffers 函数中,它还会尊重全局的 --ignore-size 配置以及文件大小未知(< 0)的情形。

  2. 哈希对比:大小相同后,通过 CheckHashes 比较两端哈希。fs/operations/operations.go 中的实现先取 src.Fs().Hashes().Overlap(dst.Fs().Hashes()),即两端远程都支持的哈希类型的交集,再从交集中任取一种进行比较——这就是为什么文档 Synopsis 中表述为“比较大小和哈希(MD5 或 SHA1)”:在大多数组合里,实际生效的是交集里这一种公共哈希。文档级命令入口在 cmd/check/check.go 中会先算出该公共哈希并打印提示:

    • 若两端存在公共哈希,日志显示 Using <hash> for hash comparisons
    • 若交集中没有任何哈希(例如某后端本身不支持哈希),则警告 No common hash found - not using a hash for checks,此时哈希检查无法进行,同名且同大小的文件会被视为“无法检查哈希”而放行。

真正把“两棵树”同步遍历并回调的骨架是 fs/operations/check.goCheckFn:它复用与 sync/copy 相同的 march 遍历机制(march.March,见 fs/march 目录),在遍历过程中回调 DstOnlySrcOnlyMatch 三个状态分支,并用 atomic 计数器累计 differences、matches、noHashes 等统计量。也就是说,checkcopy/sync 共享同一套“目录同步行走”框架,只是它的回调只做比对、不做写入——这正是“不修改源和目标”这一承诺的来源。

快速核对:--size-only

文档明确指出:如果加上 --size-only 标志,将只比较大小而不比较哈希,适合做“快速检查”(Use this for a quick check)。

rclone check gdrive:docs s3:docs-archive --size-only

适合的场景包括:你已经知道两侧哈希体系不可用、文件不会发生“等大小但内容被篡改”的情形、或只是想先粗筛一遍做巡检。源码层面,该开关由全局配置 size_only 控制(默认 false,注册于 fs/config.go),在 fs/operations/check.gocheckIdentical 中生效:一旦开启,大小比较通过后就直接返回“相同”,不再调用哈希检查函数。对应的单元测试见 fs/operations/check_test.goTestCheckSizeOnly

逐字节核验:--download

对于不支持哈希的远程,或当你希望真正校验“每一个字节”时,使用 --download 标志。文档对它的定位是:

会同时下载两端的数据,并“on the fly”地相互比对。这适用于不支持哈希的远程,或者你真的想把所有数据都校验一遍的场景。

# 对不支持哈希的后端做真正的逐字节核验
rclone check ftp:files remote:files --download

从实现上看,cmd/check/check.go 在检测到 --download 时直接改走 operations.CheckDownload,而它(见 fs/operations/check.go)把每个文件的比对函数替换为“同时打开两端流、边下载边比对”。流的实际比较由 CheckEqualReaders 完成:以 64 KiB 为缓冲分块读取双方数据流,逐块用 bytes.Equal 比对,一旦长度或内容不一致即判定不同,直到双方都读到 EOF 才算完全相同。比对过程会分别计入两端的 accounting 传输统计,因此 --download 会真实消耗下载流量,代价明显高于纯哈希比对——这也是文档建议“只在哈希不可用或确实想全量校验”时才使用它的原因。相应的端到端测试包括 fs/operations/check_test.goTestCheckDownload

单向检查:--one-way

默认情况下,check 是“双向”的:源端有而目标端没有、以及目标端有而源端没有的文件都会被记录为差异。如果你只想确认“源里的文件在目标端都存在且一致”,而不关心目标端额外多了什么文件,则加 --one-way

rclone check local:data remote:backup --one-way

文档对此的解释很直接:--one-way 只检查源端文件在目标端是否匹配,反方向不检查,因此“目标端比源端多出的额外文件不会被发现”。在 fs/operations/check.goDstOnly 回调中可以看到:当 opt.OneWay 为真时,遇到“仅目标端存在”的对象会直接跳过(return false),不再计入 missing-on-src。

典型的用途是把校验语义收窄为“备份是否完整覆盖了源数据”,而不是“两端目录是否完全镜像”。

对照校验和文件:--checkfile 与 SUM 格式

--checkfile HASH 是一个很有意思的能力:当你指定一个合法哈希名(如 md5sha1crc32)后,source:path 不再被当作目录,而是被解读为一个文本格式的 SUM 校验文件,命令转而校验“目标端文件是否与该 SUM 文件里记录的哈希一致”。

# 让 source:path 指向本地 md5 校验文件,dest:path 指向要核对的远程目录
rclone check -C md5 sums.md5 remote:data

SUM 文件每行的通用格式为:

<十六进制哈希> <空格或星号> <文件路径>

即形如 d41d8cd98f00b204e9800998ecf8427e path/to/file(文本模式用空格,二进制模式习惯用 *,两者均被接受)。SUM 文件中的哈希值按大小写不敏感处理,rclone 内部统一转成小写。这种解析规则可以在 fs/operations/check.goParseSumFile 中看到精确实现:它按行读取,用正则 ^([^ ]+) *$ 拆分“哈希”与“文件名”,对格式错误的行只给出最多前 3 条警告,并把“重复文件”的条目忽略。这样一份 SUM 文件可直接由配套命令生成:

  • rclone hashsum 负责“产出”哈希清单;
  • 校验侧除了本命令的 --checkfile,还有 rclone checksum 专门“用 SUM 文件核对目标端”,它把 sumfile 视为源、dst:path 视为目标,语义与此处完全一致,两者共享同一套 check 专用 flags(见 cmd/checksum/checksum.go)。

--checkfile 分支下,cmd/check/check.go 先用 hashType.Set(checkFileHashType) 校验哈希名是否合法(不合法时打印 hash.HelpString(0) 列出所有可用哈希),再通过 cmd.NewFsSrcFileDst(args) 把第一个参数切分为“SUM 文件所在的文件系统 + 文件名”,最后调用 operations.CheckSumCheckSum 还会做两件值得注意的事:

  • 若目标文件系统根本不支持该哈希类型(且未开 --download),会直接报错 hash type is not supported by file system
  • 遍历完目标目录后,SUM 文件中“未被任何目标文件消费”的条目会被判为 missing-on-dst(文件中多出来、云端不存在的哈希),使用 + 前缀报告——这正好与 rclone hashsum + rclone check -C 形成“生成清单→核对清单”的闭环。

--checkfile 也可配合 --download:此时不再依赖远程的存储哈希,而是把目标文件下载下来即时计算哈希与 SUM 文件比对,对应 CheckSumdownload 分支的逻辑。相关测试见 fs/operations/check_test.goTestCheckSum / TestCheckSumDownload)。

报告输出:--differ / --match / --missing-* / --error 与 --combined

check 的一大亮点是可以把结果结构化导出,便于二次处理或归档。文档规定了如下五类报告 flag,每个都接收一个文件路径参数(或写 - 表示输出到标准输出 stdout):

  • --differ:两侧都存在、但内容(大小或哈希)不一致的文件路径,每行一条;
  • --missing-on-dst:只在源端存在(目标端缺失)的文件路径;
  • --missing-on-src:只在目标端存在(源端缺失)的文件路径;
  • --match:两侧都存在且完全匹配的文件路径;
  • --error:读取或计算哈希时出错的文件路径。

例如只把“两端不一致”的文件列到 stdout:

rclone check gdrive:docs s3:docs-archive --differ -

输出文件的打开与关闭逻辑集中在 cmd/check/check.goGetCheckOpt:空字符串表示“不启用该项”,- 映射到 os.Stdout,其余情况用 os.Create 创建真实文件,并在命令结束时统一关闭。

--combined 则把所有结果合并写到一个文件(或 stdout),每行形如“一个符号 + 空格 + 路径”,风格类似 diff 输出。五种符号的含义如下表:

符号 含义
= path 该路径在源与目标中都存在,且完全相同
- path 该路径在源端缺失,只存在于目标端
+ path 该路径在目标端缺失,只存在于源端
* path 该路径在源与目标中都存在,但内容不同
! path 读取或哈希源/目标时出现错误
rclone check gdrive:docs s3:docs-archive --combined combined.txt

在实现层,fs/operations/check.goreport/reportFilename 承担所有落盘逻辑:每条路径先按需写入对应分类输出(differ/match/error/missing-on-*),若设置了 combined 则统一再追加一行带符号的记录。符号与分类的对应关系就发生在 DstOnly-)、SrcOnly+)、Match 中 differ 分支(*)、匹配分支(=)以及错误分支(!)。类别不匹配(如一边是文件、另一边是同名目录)也会被合理归类,例如源为目录而目标为文件时,该条目会按目标端缺失处理。

结果统计、退出码与并发控制

每次执行结束,check 会在日志中汇总统计信息。汇总逻辑位于 fs/operations/check.goreportResults,可输出的统计包括:

  • 源端/目标端缺失文件数(N files missing;在 SUM 校验场景,源的“缺失实体”措辞变为 N hashes missing);
  • 发现的差异总数(N differences found);
  • 检查过程中的错误数(N errors while checking);
  • 无法检查哈希的数量(N hashes could not be checked);
  • 匹配文件数(N matching files)。

只要发现任何差异,命令最终都会返回一个错误%d differences found),因此 check 的退出码适合作为 CI/CD 或定时脚本的判定依据——脚本可直接用 rclone check ... && echo "OK" 这类写法对一致性做门禁判断。

并发方面,文档明确说明默认并行校验数为 8(The default number of parallel checks is 8),对应全局选项 --checkers。默认值定义在 fs/config.go,归入 Performance 分组;在 fs/operations/check.go 中,CheckFn 用一个容量为 ci.Checkers 的 token channel(tokens: make(chan struct{}, ci.Checkers))来限制同时进行的哈希/下载检查协程数。对“文件数量巨大但单个文件很小”的校验场景,适当调高 --checkers 能显著缩短总耗时;反向地,为了不压垮弱网环境,也可以调低。并发限流行为本身也有专门测试覆盖,例如 fs/operations/check_test.go 中验证“哈希/下载确实以 --checkers 指定的并发数在跑”。

crypt 加密远程的特殊处理:cryptcheck

普通 rclone checkcrypt 远程 是不适用的——因为 crypt 在云端看到的是加密后的对象,哈希也是加密层的哈希,与明文文件并无可比性。因此文档明确指出:对于 crypt 远程,有专门的命令 rclone cryptcheck(详见 docs/content/commands/rclone_cryptcheck.md),它能够直接校验加密文件的校验和(在不解密或仅做必要解密的基础上核对明文哈希)。当你把源或目标配成 crypt: 远程时,请优先查阅并使用 cryptcheck,而非普通 check

与 check 共享的通用选项

check 并非孤立命令,它与其他目录类命令共享三类选项。以下表格完整保留了文档中的相关片段,方便你在实际拼装命令时查阅。

Check Options(check 类命令共享)

      --max-backlog int   Maximum number of objects in sync or check backlog (default 10000)

--max-backlog 限制同步/校验过程中排队等待处理的最大对象数(默认 10000),它主要用于防止海量小文件场景下内存中的待处理队列无限膨胀。

Filter Options(目录过滤)

      --delete-excluded                     Delete files on dest excluded from sync
      --exclude stringArray                 Exclude files matching pattern
      --exclude-from stringArray            Read file exclude patterns from file (use - to read from stdin)
      --exclude-if-present stringArray      Exclude directories if filename is present
      --files-from stringArray              Read list of source-file names from file (use - to read from stdin)
      --files-from-raw stringArray          Read list of source-file names from file without any processing of lines (use - to read from stdin)
      --files-from0 stringArray             Read list of source-file names from file using NUL as separator (use - to read from stdin)
  -f, --filter stringArray                  Add a file filtering rule
      --filter-from stringArray             Read file filtering patterns from a file (use - to read from stdin)
      --hash-filter string                  Partition filenames by hash k/n or randomly @/n
      --ignore-case                         Ignore case in filters (case insensitive)
      --include stringArray                 Include files matching pattern
      --include-from stringArray            Read file include patterns from file (use - to read from stdin)
      --max-age Duration                    Only transfer files younger than this in s or suffix ms|s|m|h|d|w|M|y (default off)
      --max-depth int                       If set limits the recursion depth to this (default -1)
      --max-size SizeSuffix                 Only transfer files bigger than this in KiB or suffix B|K|M|G|T|P (default off)
      --metadata-exclude stringArray        Exclude metadatas matching pattern
      --metadata-exclude-from stringArray   Read metadata exclude patterns from file (use - to read from stdin)
      --metadata-filter stringArray         Add a metadata filtering rule
      --metadata-filter-from stringArray    Read metadata filtering patterns from a file (use - to read from stdin)
      --metadata-include stringArray        Include metadatas matching pattern
      --metadata-include-from stringArray   Read metadata include patterns from file (use - to read from stdin)
      --min-age Duration                    Only transfer files older than this in s or suffix ms|s|m|h|d|w|M|y (default off)
      --min-size SizeSuffix                 Only transfer files bigger than this in KiB or suffix B|K|M|G|T|P (default off)

利用这些过滤参数可以精确控制“到底校验哪些文件”,例如 rclone check src dst --exclude "*.tmp" 可以把临时文件排除在校验范围之外;与 --checkfile 组合时,过滤掉的文件对应地也不会被计入“SUM 文件中未消费条目”的缺失统计(见 fs/operations/check.go 中通过 filter.GetConfig 过滤判断的逻辑)。

Listing Options(目录遍历)

      --default-time Time   Time to show if modtime is unknown for files and directories (default 2000-01-01T00:00:00Z)
      --fast-list           Use recursive list if available; uses more memory but fewer transactions

其中 --fast-list 在目标后端支持递归列举(如 S3、GCS 等)时使用,通过牺牲一定内存换取更少的 API 调用次数,对云存储 API 配额紧张的账号尤其有用。

实战组合:把 check 变成你的数据巡检工具

把上述选项串起来,可以得到几类高价值用法:

1. 迁移/备份后的完整性验收

rclone check local:data remote:backup --combined backup-report.txt

若无 */+/- 行且退出码为 0,即可认定备份完整一致。

2. 只关心源是否被完整覆盖的单向巡检

rclone check local:data remote:backup --one-way --differ - --missing-on-dst -

任何差异都会逐行打到 stdout,适合接入 cron 后配合邮件/告警。

3. 对不支持哈希的远程做全量字节校验

rclone check webdav:media sftp:media --download --checkers 16

--download 兜底一切哈希不可用的情况,--checkers 提升并发以缩短全量比对时长。

4. 用哈希清单做离线/跨周期校验

# 先在生产端生成清单
rclone hashsum MD5 remote:data > data.md5
# 后续随时用清单核验任意副本
rclone check -C md5 data.md5 remote:data-copy

综上,rclone check 本质上是把 sync 的遍历引擎改造成“零写入的比对器”,配合 --size-only(快)、--download(全量逐字节)、--checkfile(清单核对)、--one-way(单向)四种模式以及 --combined/--differ 等结构化报告输出,几乎可以覆盖云存储数据一致性核验的全部场景。其命令入口与底层比对逻辑分别维护在 cmd/check/check.gofs/operations/check.go,全套行为均有 fs/operations/check_test.go 中的测试用例支撑,值得在深入定制前仔细研读。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391