首页
/ rclone 操作日志标志详解:用 --differ、--match、--combined 与 --dest-after 记录同步差异与结果

rclone 操作日志标志详解:用 --differ、--match、--combined 与 --dest-after 记录同步差异与结果

2026-09-07 17:20:25作者:柏廷章Berta

本篇技术指南围绕 rclone 的操作日志标志(Logger Flags)展开:--differ--missing-on-dst--missing-on-src--match--error--combined--dest-after。这些标志让 sync/copy/move/copyto/moveto 在传输过程中把每个文件的比对结论与目标端最终状态写入报告文件,是审计同步变更、预判结果的关键手段。读完本文,你能掌握每种标志的输出格式、符号(sigil)语义、--dest-after 的 lsf 格式参数,并能结合 operationsflags 源码 理解其写入时机与已知限制。

一、Logger Flags 是什么:把比对结果落盘为报告

Logger Flags 是 rclone 文件传输类命令的一组通用 CLI 标志。每个标志接收一个文件路径作为参数(传 - 表示输出到 stdout),在命令执行期间把符合该类别的文件路径逐行(one per line)写入对应文件。它们的设计目标是让一次同步操作产生可追溯的文本报告,而不仅是终端日志。

从源码看,这些标志统一定义在 operationsflags 包,并由五个命令注册使用:rclone synccmd/sync/sync.go)、rclone copycmd/copy/copy.go)、rclone movecmd/move/move.go)、rclone copytocmd/copyto/copyto.go)和 rclone movetocmd/moveto/moveto.go)。各命令的 init() 中调用 operationsflags.AddLoggerFlags 注册标志,并在运行时调用 operationsflags.ConfigureLoggers 打开输出文件:

// cmd/sync/sync.go 中的注册模式(其他四个命令相同)
var (
    loggerOpt      = operations.LoggerOpt{}
    loggerFlagsOpt = operationsflags.AddLoggerFlagsOptions{}
)

func init() {
    cmdFlags := commandDefinition.Flags()
    operationsflags.AddLoggerFlags(cmdFlags, &loggerOpt, &loggerFlagsOpt)
    loggerOpt.LoggerFn = operations.NewDefaultLoggerFn(&loggerOpt)
}

二、五个按类别输出的标志

以下标志各把符合条件的路径一行一条写入指定文件(- 为 stdout),输出内容由各标志的帮助文本界定(见 operationsflags.go 第 54-61 行):

标志 含义(源码帮助文本) 写入内容示例
--differ FILE Report all non-matching files to this file 源与目标都存在但内容不同的路径
--missing-on-src FILE Report all files missing from the source to this file 只存在于目标端(源端缺失)的路径
--missing-on-dst FILE Report all files missing from the destination to this file 只存在于源端(目标端缺失)的路径
--match FILE Report all matching files to this file 源与目标一致的路径
--error FILE Report all files with errors (hashing or reading) to this file 读取或哈希出错的文件路径

--differ 是最典型的一个:它会写入所有“在源和目标上都存在但不同”的路径。

三、--combined:类 diff 的综合报告

--combined 标志把所有文件路径连同前导**符号(sigil)**和空格一起写入一个文件(或 stdout),形似 diff 文件:

符号 含义
= path 在源和目标上都找到且内容相同(Match)
- path 在源端缺失,即只存在于目标端(MissingOnSrc)
+ path 在目标端缺失,即只存在于源端(MissingOnDst)
* path 源和目标上都有但内容不同(Differ)
! path 读取或哈希源端/目标端时发生错误(Error)

这些符号在源码中是一组 Sigil 常量(fs/operations/logger.go 第 57-65 行):

const (
    MissingOnSrc  Sigil = '-'
    MissingOnDst  Sigil = '+'
    Match         Sigil = '='
    Differ        Sigil = '*'
    TransferError Sigil = '!'
    Other         Sigil = '?' // reserved but not currently used
)

默认写入逻辑由 NewDefaultLoggerFn 实现(logger.go 第 111-145 行):每个 sigil 对应一个 io.Writer,按 sigil 路由写纯路径;若设置了 --combined,则额外以 "%c %s\n"(符号 + 空格 + 路径)写入综合报告。写入受互斥锁保护,保证并发传输下报告行的完整性。

四、--dest-after:预测目标端同步后的最终清单

--dest-after 写出一份列表文件,格式与 lsf 命令完全一致(包括哈希、修改时间等可定制选项)。概念上它类似于 rsync 的 --itemize-changes,但并不相同——它输出的是命令执行完毕后目标端应当呈现的准确清单,因此本质上是一份预测性结果清单

4.1 控制输出格式的配套标志

为支持 --dest-afterAddLoggerFlags 还注册了一组沿用 lsf 语义的标志(operationsflags.go 第 63-73 行):

标志 默认值 说明
--format p 输出格式字符串,格式字符含义同 lsfh 生效时用 --hash 指定的哈希
--timeformat 2006-01-02 15:04:05(帮助文本) 自定义时间格式;取 max 时按目标后端的精度自动选择(见下文)
--separator ; 格式项之间的分隔符
--dir-slash true 目录名追加斜杠
--hash MD5 使用 h 格式字符时的哈希算法,可选 MD5/SHA-1/DropboxHash
--files-only true 仅列出文件
--dirs-only false 仅列出目录
--csv false CSV 输出(未显式指定 --separator 时默认改用 ,
--absolute false 路径前加 /

格式字符的解析见 LoggerOpt.SetListFormatlogger.go 第 305-364 行),支持的字符与 lsf 一致:p(路径)、t(修改时间)、s(大小)、h(哈希)、i(ID)、m(MIME 类型)、e(加密名)、o(原始 ID)、T(存储层级 Tier)、M(元数据);出现未知字符会打印 unknown format character 错误。

关于 --timeformat maxConfigureLoggers 中检测到该值时,会调用 operations.FormatForLSFPrecision(fdst.Precision()) 依据目标后端的精度自动选择纳秒级时间格式(operations.go 第 2407 行 起)。

4.2 预测机制:WinningSide

--dest-after 的每一行并非简单记录,而是由 WinningSide 函数对每个文件做“胜者推断”(logger.go 第 202-303 行):它根据 sigil 类型与当前全局配置(ci.DryRunci.SizeOnlyci.CheckSumci.IgnoreTimesci.IgnoreExistingci.Immutable 等)判定同步结束后目标端应保留源端对象还是目标端对象,再通过 PrintDestAfterlsf 格式输出该对象。例如:

  • MissingOnSrc(目标端独有):若处于 DryRun 或 copy 类命令(DeleteModeOff),目标对象保留;否则将被删除,报告中不出现;
  • Match 且启用了 --size-only/--checksum/--ignore-size 等标志时,目标对象被视为“胜者”(差异被标志忽略);
  • 任何 DryRun 场景下,除目标端缺失项外目标对象保持不变。

五、写入时机:执行中逐文件记录,而非执行后汇总

文档特别指出:这些日志标志是**在执行过程中(during execution)**对每个文件即时记录的,而不是执行结束后统一生成。因此它们最适合作为“每个文件应当发生什么”(SHOULD happen)的预测器,实际结果(DID)可能与预测不完全一致。

从源码调用链可以印证这一点:

  1. 命令初始化时通过 WithSyncLogger/WithLoggerOptLoggerFn 存入 context.Contextlogger.go 第 147-185 行);
  2. 文件比对函数 equal() 在判定大小、哈希、修改时间的每一步就回调 logger,写入 DifferMatchoperations.go 第 247-360 行);
  3. 同步引擎在执行复制、删除、错误处理时回调 MissingOnSrcMissingOnDstTransferErrorfs/sync/sync.go 第 388-1338 行 等多处)。

也就是说,报告行产生的时刻正是传输引擎做出“这个文件需要传输/跳过/删除”决策的时刻。

六、--no-traverse 下的行为退化

--no-traverse 标志被设置时,目标端不会做完整遍历,所有“仅存在于目标端”的文件都会缺席于比对视野。文档明确说明:此时涉及目标端独有文件的日志将不完整或完全缺失。源码中 ConfigureLoggers 会主动打印三条针对性警告(operationsflags.go 第 135-144 行):

  • --no-traverse does not list any deletes (-) in --combined output--combined 输出中不会出现任何 -(删除)条目;
  • --no-traverse makes --missing-on-src produce empty output--missing-on-src 输出为空;
  • --no-traverse makes --dest-after produce incomplete output--dest-after 输出不完整。

因此需要目标端独有文件信息的报告(- 符号、--missing-on-src--dest-after 的准确性)时,应去掉 --no-traverse

七、已知限制(Limitations)

这些日志标志存在若干尚不支持的场景(文档与 WinningSide 的源码注释 一致列出):

  • --max-duration / CutoffModeHard:硬性截止时间中断传输时,无法可靠预测哪些传输完成;
  • --compare-dest / --copy-dest:因为同一文件的 equal() 会被多次调用,产生重复/失真记录;
  • 一次性 server-side 移动整个目录:引擎拿不到目录内单个文件对象,逐文件记录缺失;
  • 高层重试(high-level retries):重试会造成报告中出现重复条目,如需规避可加 --retries 1 禁用重试;
  • 一些不寻常的错误场景(possibly some unusual error scenarios)。

此外再强调一次定位:报告是执行中的逐文件预测记录,实际结果可能因错误、重试或外部变更而与报告不同。

八、实战用法

以下命令均可直接复制运行(以本地与远端 remote 为例):

# 综合差异报告:所有文件带符号写入 report.txt
rclone sync /data/src remote:dst --combined report.txt

# 只要“两边都有但不同”的文件列表,输出到终端
rclone sync /data/src remote:dst --differ -

# 分别收集四类结果
rclone copy /data/src remote:dst \
    --match same.txt --differ changed.txt \
    --missing-on-dst added.txt --error errors.txt

# 预测同步后目标端的完整清单(路径+大小+ID,分号分隔,含目录时注意 --dirs-only 默认 false)
rclone sync /data/src remote:dst \
    --dest-after after.txt --format ps --separator ";"

# CSV 格式 + 按目标端精度最大化时间格式(此时 --timeformat 仅对 t 字符有意义)
rclone sync /data/src remote:dst \
    --dest-after after.csv --format pt --csv --timeformat max

# 干跑(--dry-run)下同样可用:--dest-after 会反映 DryRun 结束后“不变”的目标端状态
rclone sync --dry-run /data/src remote:dst --dest-after after-dry.txt --format p

使用要点回顾:

  1. 五个分类标志各自独立,可任意组合,- 表示 stdout;
  2. --combined 是唯一带符号的汇总报告,符号语义见第三节的 Sigil 常量;
  3. --dest-after 输出即 lsf 格式,可用 --format--separator--csv--hash--absolute 等标志定制(见第四节参数表);
  4. 避免与 --no-traverse--compare-dest/--copy-dest--max-duration(Hard 模式)及默认多层重试混用,否则报告不完整或含重复。

相关源码与文档

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

项目优选

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