rclone md5sum 命令详解:为云端对象生成与校验 MD5 清单
导读
rclone md5sum 是 rclone 从 v1.02 版本起提供的一等命令,用于把远程存储(remote)上某个路径内的所有对象一次性输出为一份与 GNU/Linux 标准 md5sum 工具兼容的校验清单。本文从 rclone_md5sum 命令文档 出发,结合 cmd/md5sum/md5sum.go、cmd/hashsum/hashsum.go、fs/operations/operations.go 与 fs/operations/check.go 等源码,讲清该命令的两种取哈希模式、stdin 管道用法、逐项参数含义,以及用 -C/--checkfile 做整目录批量校验的实战方案。
1. 命令定位:一个 rclone 版的 “md5sum -R”
rclone md5sum 的核心能力一句话概括:把远程路径下的所有对象,逐个计算 MD5,并按标准 md5sum 输出格式打印。其命令定义为:
rclone md5sum remote:path [flags]
默认行为是「远程对象逐行输出」,格式与标准 md5sum 工具一致,即每行由三部分组成:
<hash> <对象相对路径>
即 32 位十六进制 MD5(小写),后接两个空格,再接对象在 remote:path 下的相对路径。这样的输出可以被标准的 md5sum -c 或 rclone 自身的 -C 校验逻辑直接消费。
从源码看,该命令的骨架非常简单:cmd/md5sum/md5sum.go 在 init() 中通过 cobra 把 commandDefinition 注册到根命令,并调用 hashsum.AddHashsumFlags() 挂载共享参数;真正的执行逻辑(L43-L65)在解析参数后直接委托给 fs/operations 包中的 operations.HashLister / operations.CheckSum。它本身不重复实现哈希逻辑,这一点也是理解本命令架构的关键。
1.1 与 hashsum、sha1sum 的关系
MD5 并不是 rclone 唯一支持的校验算法。rclone md5sum 本质上只是通用命令 rclone hashsum MD5 的一个专用别名:
rclone md5sum remote:path # 等价于
rclone hashsum MD5 remote:path
对应关系在 cmd/md5sum/md5sum.go 的 Long 描述中明确给出,并且执行路径完全一致:md5sum 在执行时以固定哈希类型 hash.MD5 调用 hashsum 包共享的同一批函数(见 hashsum.go#L19-L24 的共享全局变量)。SHA-1 亦有同名专用命令 rclone sha1sum,三者共用同一组实现与参数(AddHashsumFlags 注释)。
对其它算法,请直接使用 rclone hashsum 命令文档。在终端输入 rclone hashsum(不带参数)即可打印当前版本全部受支持哈希算法的列表;算法名不区分大小写,输出统一为小写。rclone 内建注册的算法及其十六进制宽度在 fs/hash/hash.go#L122-L132:
| 算法 | 别名 | 十六进制长度(字符) |
|---|---|---|
| md5 | MD5 | 32 |
| sha1 | SHA-1 | 40 |
| whirlpool | Whirlpool | 128 |
| crc32 | CRC-32 | 8 |
| sha256 | SHA-256 | 64 |
| sha512 | SHA-512 | 128 |
| blake3 | BLAKE3 | 64 |
| xxh3 | XXH3 | 16 |
| xxh128 | XXH128 | 32 |
说明:上表仅表示 rclone 内核对各算法的内置支持;某条具体的远端(remote)是否原生提供某类哈希,取决于该后端自身能力(详见第 2 节)。
2. 两种取哈希模式:远程查询 vs 本地下载
rclone md5sum 对每个对象计算 MD5 有两种途径,分别由是否传 --download 决定。
2.1 默认模式:向远端查询哈希(服务端直出)
默认情况下,rclone 不下载文件,而是向远端请求对象自带的 MD5 哈希值。许多对象存储(含大量 S3/云盘类后端)会在存储元数据中附带对象的 ETag/校验值,rclone 通过 o.Hash(ctx, ht) 直接读取,速度快、几乎不消耗带宽和配额。
对应的实现分支在 fs/operations/operations.go#L944-L961:非 download 模式下调用 o.Hash(ctx, ht) 获取哈希;若远端返回 hash.ErrUnsupported,则说明该远端不支持 MD5。
局限性随之而来:如果远端本身不提供 MD5(例如某些只提供 SHA-1、CRC32 或自研校验的后端),默认模式下该对象不会返回任何哈希——这正是原文档中 “If MD5 is not supported by the remote, no hash will be returned” 的含义。此时该对象的校验行会被跳过,同时 rclone 会记录一条错误日志并计入错误统计。
2.2 --download:下载后本地计算
传入 --download 后,rclone 会把文件从远端下载下来并在本地流式计算 MD5,从而“为任意远端启用 MD5”。代价是需要实际传输数据,占用带宽并计入传输统计。
实现上,operations.go#L902-L943 的流程为:通过 Open(内部经 NewReOpen 支持断点重启)打开对象 → 用 accounting.Stats().NewTransfer 计入传输 → hash.NewMultiHasherTypes 构造多路哈希器 → io.Copy 边下载边喂给哈希器 → 最终 SumString 输出。
因此选型建议清晰:
| 场景 | 推荐模式 | 原因 |
|---|---|---|
| 远端原生支持 MD5 | 默认(不带 --download) |
服务端直出,零带宽成本,速度快 |
| 远端不支持 MD5、或想验证上传内容的“真身” | --download |
下载本地计算,任意远端可用 |
| 数据量极大、仅想核对元数据哈希 | 默认模式 | 避免全量回源传输 |
2.3 并发与输出对齐的实现细节
从源码结构可以推断,md5sum 的并发模型与 --checkers/--transfers 全局参数联动:
- HashLister(operations.go#L969-L996) 会并行列出目录并对每个对象启动 goroutine 计算哈希;
- 默认并发上限取自全局配置
--checkers;当使用--download时则自动切换为--transfers(因为此时对象是真正在“传输”而非“检查”)。
输出格式由 hash.Width() 对齐列宽(见 fs/hash/hash.go#L140-L149):每行输出 "%*s %s\n"——哈希右对齐到该算法的固定宽度,再加两个空格和对象相对路径。MD5 十六进制宽度恒为 32,因此不管哈希长短,所有行都整齐对齐,便于 diff 与脚本处理。
3. 读取标准输入:对管道数据计算 MD5
rclone md5sum 还支持从 stdin 读取数据做一次性计算。当省略 remote:path 参数时,命令总是读取标准输入;当传入一个连字符 - 作为参数、且 stdin 确实有管道数据可读时,同样进入 stdin 模式。例如:
cat data.bin | rclone md5sum -
会输出形如 2fd4e1c6... - 的一行(文件名位置显示为 -,代表数据来自标准输入)。
该行为的判定逻辑在 cmd/hashsum/hashsum.go#L58-L82 的 CreateFromStdinArg:
len(args) == 0:缺少参数,总是读 stdin;args[0] == "-":只有当os.Stdin不是字符设备(即确实存在重定向/管道输入,通过os.ModeCharDevice位判断)时才读 stdin;否则-会被当作字面量,视为一个普通相对路径来解析。
对应数据处理函数为 operations.go 的 HashSumStream(L1001-L1018):它对输入流做一次流式计算(io.Copy 到多路哈希器),再按 "%*s -\n" 输出。stdin 模式天然是本地计算,因此不存在远端不支持 MD5 的问题。
4. 专属参数逐项详解
原文档列出的命令专属参数共 5 个。这四个除 -h 外的选项全部声明于 cmd/hashsum/hashsum.go#L33-L38,并在 md5sum、sha1sum、hashsum 三个命令间共享:
| 选项 | 简写 | 默认值 | 说明 |
|---|---|---|---|
--base64 |
无 | false |
以 base64 编码输出哈希,替代默认的十六进制 |
--checkfile string |
-C |
空 | 不再打印哈希,而是读取指定的 SUM 清单文件并逐项校验 |
--download |
无 | false |
下载文件后在本地计算哈希;不指定时向远端请求哈希 |
--output-file string |
无 | 空 | 将哈希输出到指定文件,而不是终端 |
-h, --help |
无 | — | 打印 md5sum 帮助 |
各参数要点如下:
4.1 --base64:base64 编码输出
默认十六进制小写输出(MD5 为 32 字符)。加 --base64 后改输出 URL-safe base64 编码(无填充),对齐宽度由 hash.Width(ht, true) 统一换算(base64.URLEncoding.EncodedLen(16),即 22 字符),行格式不变。适用场景是下游消费方本身使用 base64 表示哈希(如部分 REST API、JSON 元数据)。
4.2 -C, --checkfile:对照清单做批量校验
不输出哈希,而是与给定 SUM 文件逐行比对,作用类似本地 md5sum -c。注意,这里的 “SUM file” 可以是本地文件也可以是远端路径,rclone 通过 cmd.NewFsFile 以 fs 抽象统一打开。详细校验语义见第 5 节。
4.3 --output-file:落盘而非刷屏
把结果写入文件而非 stdout。实现上由 GetHashsumOutput(hashsum.go#L40-L56)os.Create 目标文件并在命令结束时关闭。它同样作用于 stdin 模式:... | rclone md5sum - --output-file sums.md5 会把计算结果写进文件。建议与 --base64、-C 组合前先明确输出目标,避免歧义。
4.4 执行顺序(源码级)
cmd/md5sum/md5sum.go#L43-L65 展示了完整的执行优先级:
- 参数个数限制为 0~1(
cmd.CheckArgs(0, 1, ...)); - 先尝试 stdin 分支(
CreateFromStdinArg),命中则直接完成并返回; - 构造源 fs(
cmd.NewFsSrc(args)); - 若指定了
-C/--checkfile→ 走operations.CheckSum校验路径; - 否则若未指定
--output-file→operations.HashLister输出到 stdout; - 指定了
--output-file→ 先创建输出文件,再把HashLister的结果写入该文件。
由此可以推断:--checkfile 与 --output-file/--base64 同时使用时,实际生效的是校验路径,--checkfile 的优先级最高。
5. 实战:用 -C/--checkfile 校验整个远程目录
5.1 两步走流程
第一步,先生成基准清单(默认远程查询;对不支持 MD5 的远端加 --download 兜底):
rclone md5sum remote:path > sums.md5
# 或
rclone md5sum remote:path --download --output-file sums.md5
第二步,之后任意时刻拿同一清单回验(本地文件或远端清单均可):
rclone md5sum remote:path -C sums.md5
rclone md5sum remote:path -C remote:backup/sums.md5 --download
这样便能验证「当前目录内容是否与历史快照完全一致」。
5.2 SUM 文件解析规则(源码级)
operations.CheckSum(fs/operations/check.go#L409-L470)把 sum 清单读入并交给 ParseSumFile(check.go#L569-L623)解析,其关键规则如下:
- 每行格式须匹配正则
^([^ ]+) *$,即“哈希 + 空格 + 空格或*+ 文件名”——同时兼容文本模式(md5sum file)与二进制模式(md5sum *file)的输出,两种模式下文件名与哈希之间都用两个空格分隔; - 文件名会被做归一化处理(如必要的 Unicode 规范化),以保证与远端相对路径匹配;
- 内部统一使用小写哈希比较;
- 格式非法或重复文件名的行会告警(前 3 条逐条打出,后续抑制并汇总计数),格式非法的行被跳过。
5.3 校验结果的语义
逐个对象比对时,每条结果在 stdout 上以“标记 + 空格 + 文件名”形式输出,标记含义由 check.go 的 matchSum(L533-L563) 等函数驱动:
| 标记 | 含义 |
|---|---|
= |
哈希一致(匹配);若对象因远端不支持而无法计算哈希,也会被计入“无法检查”并视同匹配 |
* |
哈希不一致(files differ) |
! |
出错(计算失败)或清单中存在重复条目 |
+ / - |
某一侧缺失:sum 文件里有但远端没有、或远端存在但 sum 文件里没有 |
校验结束后,rclone 会打印汇总日志(见 reportResults,check.go#L240-L272),例如 N matching files、N differences found、N errors while checking、N hashes could not be checked 以及缺文件/hash 的统计。只要存在差异或错误,命令最终返回错误并产生非零退出码,方便在脚本中用 $? 或 CI 判断。
另外需注意:CheckSum 在非 --download 模式下,若目标远端根本不支持 MD5,会直接报错 hash type is not supported by file system;这类远端请务必配合 --download 校验。
6. 组合过滤与列出选项
md5sum 会遍历 remote:path 下整个目录树,因此 rclone 的目录遍历过滤参数对它完全适用(versionIntroduced 注解中 groups: "Filter,Listing" 即表明该命令挂在这两个公共 flag 组下)。原文档中与其它命令共享的参数如下,可用于把校验范围精确收缩到某类文件。
6.1 Filter Options(目录列表过滤)
| 选项 | 说明 |
|---|---|
--delete-excluded |
删除被排除到同步之外的目标文件(对纯读取类命令通常无意义,保留兼容) |
--exclude stringArray |
排除匹配 pattern 的文件 |
--exclude-from stringArray |
从文件读取排除模式(用 - 表示从 stdin 读取) |
--exclude-if-present stringArray |
若目录中存在指定文件则排除该目录 |
--files-from stringArray |
从文件读取要处理的源文件名列表(- 表示 stdin) |
--files-from-raw stringArray |
从文件读取源文件名列表,不做任何行处理(- 表示 stdin) |
--files-from0 stringArray |
从文件读取源文件名列表,以 NUL 作为分隔符(- 表示 stdin) |
-f, --filter stringArray |
添加一条文件过滤规则 |
--filter-from stringArray |
从文件读取过滤规则(- 表示 stdin) |
--hash-filter string |
按哈希 k/n 划分文件名,或按 @/n 随机划分 |
--ignore-case |
过滤时忽略大小写 |
--include stringArray |
仅包含匹配 pattern 的文件 |
--include-from stringArray |
从文件读取包含模式(- 表示 stdin) |
--max-age Duration |
仅处理比该时间更“年轻”的文件,单位 s 或后缀 ms|s|m|h|d|w|M|y(默认 off) |
--max-depth int |
限制递归深度(默认 -1,表示不限制) |
--max-size SizeSuffix |
仅处理小于该大小的文件,单位 KiB 或后缀 B|K|M|G|T|P(默认 off) |
--metadata-exclude stringArray |
排除匹配的元数据 |
--metadata-exclude-from stringArray |
从文件读取元数据排除规则(- 表示 stdin) |
--metadata-filter stringArray |
添加元数据过滤规则 |
--metadata-filter-from stringArray |
从文件读取元数据过滤规则(- 表示 stdin) |
--metadata-include stringArray |
仅包含匹配的元数据 |
--metadata-include-from stringArray |
从文件读取元数据包含规则(- 表示 stdin) |
--min-age Duration |
仅处理比该时间更“年长”的文件(默认 off) |
--min-size SizeSuffix |
仅处理大于该大小的文件(默认 off) |
典型用法举例:
# 只给目录下所有 *.iso 生成清单(递归全目录但按扩展名过滤)
rclone md5sum remote:path --include "*.iso" --include-from other.txt --exclude "*.part"
# 只处理小于 1GiB 的文件,避免对大文件做下载式校验
rclone md5sum remote:path --min-size 0 --max-size 1GiB --download
过滤类参数的具体语义以 flags 全局选项页 及各命令文档为准。
6.2 Listing Options(目录列出选项)
| 选项 | 说明 |
|---|---|
--default-time Time |
当文件/目录的修改时间未知时用于展示的时间(默认 2000-01-01T00:00:00Z) |
--fast-list |
若后端支持则使用递归列表,内存占用更高但事务请求更少 |
--fast-list 对包含海量小对象的远端尤其有价值:它以“少而大的目录列举”代替逐目录请求,可显著减少 API 调用次数,代价是更高的内存占用。在超大目录上跑 md5sum 时值得开启对比效果。
7. 小结与相关文档
rclone md5sum 是 rclone 校验体系的“入口级”命令:默认服务端直出、--download 兜底本地计算、-C 完成清单校验、--base64 适配下游格式,配合 Filter/Listing 选项可精确圈定校验范围。理解它的关键在于记住它与 hashsum/sha1sum 共享同一套实现,差异仅是固定算法 hash.MD5。
可继续阅读的相关仓库文档:
- rclone hashsum 命令文档:任意算法的通用哈希清单命令(含算法列表)
- rclone sha1sum 命令文档:SHA-1 专用别名
- rclone 命令总览 与 全局参数页:查看
--checkers、--transfers、过滤/列出等全局参数
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0631
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python09
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00