rclone lsjson 详解:以 JSON 格式机器化输出云端目录与对象清单
2026/9/8 21:29:23 网站建设 项目流程

rclone lsjson 详解:以 JSON 格式机器化输出云端目录与对象清单

【免费下载链接】rclone"rsync for cloud storage" - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Azure Blob, Azure Files, Yandex Files项目地址: https://gitcode.com/GitHub_Trending/rc/rclone

rclone 的lsjson命令用于把远程路径下的目录与文件(对象)以结构化 JSON形式输出,是 rclone 各列表命令(ls/lsl/lsd/lsf/lsjson)中专为“机器可读”设计的一支。无论是做文件系统盘点、写自动化脚本按字段筛选云端文件,还是通过 rclone 的 RC 接口(operations/listoperations/stat)做编程式查询,lsjson的完整字段与选项语义都值得深入掌握。读完本文,你将能精确理解其输出的每一个 JSON 字段、灵活使用--hash--stat--recursive--metadata等选项,并了解其底层在 fs/operations/lsjson.go 中的实现原理。本文以官方命令文档 rclone_lsjson.md 为主体,辅以命令入口与核心实现源码展开。

命令概述与输出样例

命令的基本用法是:

rclone lsjson remote:path [flags]

它会把remote:path中的目录与文件/对象以Item 数组的形式输出,每个 Item 形如:

{ "Hashes" : { "SHA-1" : "f572d396fae9206628714fb2ce00f72e94f2258f", "MD5" : "b1946ac92492d2347c6235b4d2611184", "DropboxHash" : "ecb65bb98f9d905b70458986c39fcbad7715e5f2fcc3b1f07767d7c83e2438cc" }, "ID": "y2djkhiujf83u33", "OrigID": "UYOJVTUW00Q1RzTDA", "IsBucket" : false, "IsDir" : false, "MimeType" : "application/octet-stream", "ModTime" : "2017-05-31T16:15:57.034468261+01:00", "Name" : "file.txt", "Encrypted" : "v0qpsdq8anpci8n929v3uu9338", "EncryptedPath" : "kja9098349023498/v0qpsdq8anpci8n929v3uu9338", "Path" : "full/path/goes/here/file.txt", "Size" : 6, "Tier" : "hot", }

需要说明的是:上面是“字段齐全”时的示例形态,实际输出中哪些属性出现,取决于所用后端(backend)与命令行选项,详见下文。

从源码看,该命令由 cmd/lsjson/lsjson.go 注册与实现(cobra.CommandUse: "lsjson remote:path"),官方文档头部标注其自v1.37引入。真正生成每个 Item 的逻辑在 fs/operations/lsjson.go:命令只是按"[","item,item,...","]"的形式逐行打印(items 之间以,\n分隔),也就是说整个输出既可以作为一个完整 JSON blob 解析,也可以逐行解析——除--stat模式外,每个 item 独占一行,方便流式处理。

Item 字段逐一解读

每个 Item 的结构对应源码中的 ListJSONItem 结构体。其核心字段如下:

字段类型含义何时出现
Pathstring条目相对被列出目录的路径始终
Namestring条目文件名(Path的 basename)始终
Sizeint64文件大小(字节)始终
IsDirbool是否为目录始终
ModTimestringRFC3339 格式修改时间默认出现;--no-modtime时为空字符串
MimeTypestring文件 MIME 类型默认出现;--no-mimetype时为空字符串
Hashesobject各哈希算法→值的字典仅指定--hash--hash-type
IDstring后端对象 ID(若后端提供)实现了fs.IDer接口时
OrigIDstring底层(解包后)对象 ID--original时,且需底层支持
Tierstring存储层/归档等级(如hot后端支持 GetTier 时
Encryptedstring加密后的名字仅 crypt 远程 +--encrypted
EncryptedPathstring加密后的完整路径仅 crypt 远程 +--encrypted
IsBucketbool是否为 bucket仅 bucket 型远程且值为 true 时
Metadataobject文件/目录元数据--metadata

与后端相关、按需出现的字段

  • IsBucket:只会在 bucket 型远程(如 s3、gcs、b2、azureblob 等)列出 bucket 目录时出现,且当值不为true时整个字段会被省略。对应实现中,newListJSON会判断features.BucketBased && remote == "" && fsrc.Root() == "",只有“在 bucket 型远程的根上列目录”才会把目录标记为 bucket。
  • Encrypted/EncryptedPath:只对 crypt 加密远程有意义,且(正如后文所说)只有当同时给出--encrypted时才会出现在输出里。源码里还做了一层保护:若对非 crypt 远程使用--encrypted,会直接报错the remote needs to be of type "crypt"
  • ID/OrigIDID是当前对象的 ID;OrigID则是解包后底层对象的 ID,源码中通过fs.UnWrapObject(o)取得,便于在 combine、crypt 等叠加远程上追溯到真正底层存储的 ID。二者都要求后端实现了fs.IDer(注释为 “ID of the underlying Object”)。
  • Tier:对支持分层存储的后端(可看 tiers 相关文档),若features.GetTier可用,会额外返回对象所在的存储层。

选项详解

lsjson专用选项由 cmd/lsjson/lsjson.go 通过 cobra flags 注册,对应的是 ListJSONOpt 结构体。完整清单如下:

--dirs-only Show only directories in the listing --encrypted Show the encrypted names --files-only Show only files in the listing --hash Include hashes in the output (may take longer) --hash-type stringArray Show only this hash type (may be repeated) -h, --help help for lsjson -M, --metadata Add metadata to the listing --no-mimetype Don't read the mime type (can speed things up) --no-modtime Don't read the modification time (can speed things up) --original Show the ID of the underlying Object -R, --recursive Recurse into the listing --stat Just return the info for the pointed to file

控制列出“哪些条目”:--dirs-only--files-only

默认行为是目录与文件都列出,可用这两个选项收窄范围:

  • --dirs-only:只返回目录;
  • --files-only:只返回文件/对象。

源码中按“Dirs / Files 两个开关”组合过滤:!FilesOnly && DirsOnly时不再输出文件;FilesOnly && !DirsOnly时不再输出目录。fs/operations/lsjson_test.go中的TestListJSON用例(FilesOnlyDirsOnly两表)直接验证了这一行为。需要留意,两个开关同时给定时逻辑上等同于两者都要(等价于默认值),从源码分支FilesOnly,DirsOnly同时为 true 时 dirs/files 均保持 true 可得到印证。

是否递归:-R, --recursive

lsjson默认不递归,仅列出所给路径这一层;使用-R才会递归遍历其下所有层级。递归深度还可用共享过滤选项--max-depth N进一步限制。测试用例(Recurse场景)断言递归后子目录里的sub/file2也会被返回。

输出目标自身的信息:--stat

不加--stat时输出对象数组;加上后输出关于该条目本身的单个 JSON blob(不再是数组),类似于“stat 一个文件/目录”。这在命令入口中有直接体现:cmd.CheckArgs(1,1,...)后若statOnly则走cmd.NewFsFile(args[0])+operations.StatJSON,且打印时用json.MarshalIndent(item, "", "\t")输出带缩进的单个对象。

--stat的语义细节(来自官方文档,与 StatJSON 实现 完全对应):

  • 如果被指的条目不存在,命令会返回错误;
  • 但对 s3、gcs、b2、azureblob 这类bucket 型后端,由于无法区分“空目录”与“不存在的目录”,当目标不存在时会返回一个空目录(而不是报错);
  • --stat对远程根、普通目录、普通文件的行为在TestStatJSON中都有覆盖,例如目录名带不带尾部斜杠(subsub/)结果等价;
  • 结合--files-only/--dirs-only使用可以非常高效地探测“某个路径下是否存在文件/目录”——RC 接口文档中甚至专门提示:如果只关心文件,设filesOnly选项会高效得多。

实现上,StatJSON会依次尝试:把根当作目录处理;用fsrc.NewObject(remote)探测文件(对fs.ErrorObjectNotFoundfs.ErrorIsDir做了区分);对 bucket 型后端优先用ListP直接列目标目录本身(比列其父目录更省事务,源码注释专门说明了这一点);都不命中时再回退到列父目录、按名字(对大小写不敏感的后端用EqualFold比较)找到真正的目录项,从而尽量保留 ID 等真实元数据。

控制是否附带额外请求代价的字段:--no-modtime--no-mimetype

  • --no-modtime:不读取修改时间,输出中ModTime为空白。在读取 ModTime 需要额外请求的后端(例如 s3、swift)上可以显著提速;
  • --no-mimetype:不读取 MIME 类型,输出中MimeType为空白。同样可让 s3、swift 这类后端更快。

源码中这两个开关是“默认读取、显式关闭”模型:只有!opt.NoModTime时才填充ModTime、只有!opt.NoMimeType时才调用fs.MimeTypeDirEntry获取类型。测试用例NoModTimeNoMimeType也断言了对应字段会输出为空字符串。

哈希:--hash--hash-type

  • 若不给--hashHashes字段整体省略;
  • --hash-type可以(多次重复给出以)只输出指定类型的哈希,例如--hash-type md5 --hash-type sha1
  • 只要给了--hash-type,就隐含了--hash,无需再显式写--hash

在实现里,默认hashTypes = fsrc.Hashes().Array()(列出后端支持的全部哈希),一旦给出--hash-type便重置为指定类型列表。测试HashTypes用例验证了只请求 MD5 时输出里只有 MD5 键。

加密名称:--encrypted

当远程是 crypt 类型时,加上--encrypted会让输出额外包含加密态的名字Encrypted(名字的加密形式)与EncryptedPath(完整加密路径)。不加该选项时,即使远程是加密远程,这两个字段也不会出现(源码中只有opt.ShowEncrypted为 true 才创建 cipher 并调用EncryptFileName/EncryptDirName)。可用于排查、调试加密层与真实存储名的对应关系。

元数据:-M, --metadata

加上-M/--metadata后,输出中会多出一个Metadata属性,内容是 rclone 标准格式的元数据 JSON 对象,其格式规范见 docs.md 的 Metadata support 章节。实现上它会调用fs.GetMetadata(ctx, entry)逐个条目读取元数据。需要注意,命令入口在创建任何后端之前会把opt.Metadata同步到全局配置ci.Metadata(见 cmd/lsjson/lsjson.go),因为 rclone 的元数据框架依赖全局开关决定后端是否采集元数据。

底层 ID:--original

对某些“包装型”后端(例如 crypt、combine 等),外层对象 ID 与真正底层对象 ID 不同;--original会在输出中附带OrigID,即底层原始对象的 ID。源码通过fs.UnWrapObject(o)逐层解包后再取ID()

时间精度:RFC3339 与按后端精度格式化

ModTime采用 RFC3339 格式,秒的小数位数取决于该远端能保存的时间精度,最高到纳秒级。官方文档给出的规律是:

  • Google Drive 这类能精确到毫秒的后端,总是输出 3 位小数,如"2017-05-31T16:15:57.034+01:00"
  • Dropbox、Box、WebDAV 等只精确到秒的后端,则不输出小数位,如"2017-05-31T16:15:57+01:00"

对应源码是 lsjson.go 的 formatForPrecision 函数:它依据fsrc.Precision()落入不同的 Go 时间格式模板,从纳秒(9 位)逐级退化到毫秒(3 位)、秒(time.RFC3339)。Timestamp类型自定义了MarshalJSON:时间戳为零值时输出空字符串""(这与--no-modtime行为对应),否则按所选精度格式化成字符串。

Path 字段的语义与输出形态

Path字段只显示所列出远程路径之下的目录层级。官方文档举例:如果remote:path下有一个文件subfolder/file.txt,则file.txtPathsubfolder/file.txt,而不会remote:path/subfolder/file.txt。并且当不使用--recursive时,Path恒等于Name(因为这一层里每个条目的路径就是其自身名字)。实现上Path取自entry.Remote()Name则取path.Base(entry.Remote());只有根目录这一特殊情况Name会被置空。

输出形态上,整个结果既可以当作一个 JSON 数组整体解析,也可以逐行处理(除--stat外每个 item 单独一行)。这在命令入口打印逻辑中很直观:先打印[,每个 item 打印一行,item 之间以,\n相连,最后打印]

不存在的目录与列表方式(fast-list / ListR)

列出不存在的目录会报错——唯一的例外是“无法拥有空目录”的远程,即 s3、swift、gcs 等 bucket 型远程(它们天然无法区分空目录与不存在)。这与--stat对 bucket 型后端返回空目录的语义互为呼应。

关于遍历方式,官方文档提醒:默认情况下,列表命令会优先使用更占内存但事务更少的递归列目录方法(ListR)。可以通过--disable ListR禁用该行为,相关背景见 全局 --fast-list 说明(另可参考命令文档 rclone)。实现上,ListJSON正是通过 walk.ListR 驱动遍历,并在回调里对每个fs.DirEntry调用entry()转成ListJSONItem

与列表相关的过滤与公共选项

文档明确指出:“任何过滤选项都可以用于本命令”。lsjson除了上面列出的专属选项外,还共享以下过滤选项

--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 smaller 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)

以及列表选项

--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

过滤规则的完整语法(include/exclude/filter 规则、--min-age/--max-size等单位与解析)见 filtering.md。这些共享过滤选项在命令的Annotations中被归入"Filter,Listing"两组(源码注释),因此通过rclone help flags filteringrclone help flags listing也能查看到对应帮助。

与其它列表命令的分工对比

rclone 围绕“列目录/文件”提供了一族命令,各有定位:

  • ls:仅列出对象的大小与路径
  • lsl:列出修改时间、大小与路径
  • lsd:仅列出目录
  • lsf:以易于解析的格式列出对象与目录
  • lsjson:以 JSON 格式列出对象与目录

官方文档给出的设计定位非常清晰:

  • lslsllsd面向人类阅读
  • lsf面向人与机器都能读
  • lsjson面向机器阅读(因此字段语义最严谨、最适合程序化消费)。

两类递归习惯也要注意区分:

  • lslsl默认递归——想停止递归请用--max-depth 1
  • lsdlsflsjson默认不递归——想递归请加-R

以上并列命令的介绍可在 rclone_ls.md、rclone_lsl.md、rclone_lsd.md、rclone_lsf.md 以及公共列表帮助 cmd/ls/lshelp/lshelp.go 中交叉查看。

底层复用:不只命令行能用

值得强调的是,ListJSON/StatJSON并不是lsjson命令独享的内部逻辑,而是 fs/operations 包 提供的通用能力,被多个上层功能复用:

  • RC 接口operations/listoperations/stat两个 RPC 直接封装了ListJSON/StatJSON(见 fs/operations/rc.go)。前者把每个 item 收集进list数组返回,后者返回item(找不到时为null)。RC 请求参数里的opt字典与ListJSONOpt一一对应(recursenoModTimeshowHashhashTypesdirsOnlyfilesOnlymetadata等)。这意味着在rclone rcd下通过 HTTP/WebSocket 也能以同样的字段语义获取 JSON 清单。
  • 同步/拷贝的--json输出:在 copy/sync 的 dest-after 日志等场景中,fs/operations/logger.go 内部同样构造了ListJSONOpt并调用LJ.entry()把传输结果格式化成同构的 JSON item,因此两处的 JSON 字段格式保持完全一致。
  • lsf 等命令lsf的格式化逻辑(见 fs/operations/operations.go 中 ListFormat)同样围绕ListJSONItem取数,说明ListJSONItem是整个 operations 层统一的对象清单数据模型。

正因为存在这一层复用,把lsjson输出中的字段语义理解透彻,也就同时掌握了 RC 接口返回结构与若干“以 JSON 汇报结果”的命令行为。

测试与验证

该功能的自动化测试集中在 fs/operations/lsjson_test.go:

  • TestListJSON:覆盖默认、FilesOnlyDirsOnlyRecurse、子目录、NoModTimeNoMimeTypeShowHashHashTypesMetadata等组合,验证每种选项下的字段取舍;
  • TestStatJSON:覆盖--stat语义下对根、目录、带尾斜杠目录、文件、不存在的路径,以及FilesOnly/DirsOnly组合时的返回值;
  • TestStatJSONMemory:专门验证 bucket 型后端--stat走“直接列目标目录”快路径时,计入的条目统计是否正确。

此外 fs/operations/rc_test.go 对operations/listoperations/stat两个 RC 端点做了端到端断言。读者若想验证自己对某选项的理解,可直接运行对应测试或对一个真实远程执行rclone lsjson remote:path [选项]观察输出差异。

小结

lsjson是 rclone 各列表命令中唯一以“机器可读 JSON”为目标的输出通道,其字段集、精度规则与选项语义都经过严格设计:--files-only/--dirs-only控制条目类型,-R控制递归,--hash/--hash-type/--metadata/--original/--encrypted追加额外信息,--no-modtime/--no-mimetype在特定后端上换取速度,--stat则把数组语义切换为单条目探测。理解其输出字段与底层 ListJSONItem 结构的对应关系,能帮助你在脚本、CI 流程与基于 RC 接口的程序化场景中稳定可靠地消费 rclone 的云端清单数据。

【免费下载链接】rclone"rsync for cloud storage" - Google Drive, S3, Dropbox, Backblaze B2, One Drive, Swift, Hubic, Wasabi, Google Cloud Storage, Azure Blob, Azure Files, Yandex Files项目地址: https://gitcode.com/GitHub_Trending/rc/rclone

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询