☰
rclone touch 命令完全指南:创建空文件与批量修正远程存储时间戳
2026/11/1 5:42:43 网站建设 项目流程

rclone touch 命令完全指南:创建空文件与批量修正远程存储时间戳

【免费下载链接】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 touch是 rclone 中一条功能直接但底层实现颇具巧思的命令:它的作用与 Unix/Linux 的touch一致——为一个或多个远程文件设置修改时间(modification time),当目标路径不存在时则自动创建零字节空文件。它尤其适合在对象存储、网盘等场景下“打占位标记”、为缓存类远程强制刷新、或对海量文件统一校准时间戳。阅读本文后,你将掌握touch的全部自有参数(时间戳格式、递归、禁用创建、元数据写入)、它在递归模式下与过滤器/试运行体系的联动方式,并能结合 cmd/touch/touch.go 源码理解其创建文件、更新时间与递归调度的真实执行链路。

本文对应的命令参考文档为 docs/content/commands/rclone_touch.md(该文件由cmd/touch/下的源码在发布时自动生成,正文顶部亦有注明 "autogenerated - DO NOT EDIT")。命令自 v1.39 引入(见源码 touch.go 中的versionIntroduced: v1.39注解)。

一、命令概述与基本用法

命令的完整形态为:

rclone touch remote:path [flags]

其核心语义只有一句话:把remote:path指定的一个或多个文件的修改时间设置为当前时间。结合不同的参数,还可以退化为以下行为:

  • 若remote:path指向的文件不存在,则创建一个零字节文件;
  • 若同时带了--no-create或--recursive,则不创建新文件;
  • 若路径已存在且是目录,则对目录内的文件修改时间(是否递归取决于--recursive);
  • 若指定了--timestamp,则把时间设置为指定值而非当前时间;
  • 创建新文件时可通过--metadata-set附带元数据。

由于该命令直接操作远端对象的时间与存在性,执行前建议先理解它在源码中的路径解析方式:命令参数中remote:之后的部分会被fspath.Split拆成"根"与"相对路径"两部分(见 newFsDst),即使remote:path末尾带斜杠或以目录结尾,也不会报错——这正是 touch 允许参数为目录路径的前提。

二、touch 自有参数详解

touch的专属参数只有 4 个,均在 touch.go 的 init 函数 中注册:

参数简写默认值含义
--no-create-Cfalse目标文件不存在时不创建(使用--recursive时隐含启用)
--recursive-Rfalse递归处理路径下所有文件
--timestamp string-t空(即当前时间)使用指定时间替代当前时间
--localtime无false解析--timestamp时按本地时区而非 UTC

以下逐一说明各参数的语义与使用边界。

1.--timestamp/-t:指定精确时间戳

默认情况下 touch 将时间设为"现在"。如需设置为过去或未来的某个确定时刻,使用--timestamp。该参数支持三种写法(源码 parseTimeArgument 中定义了对应的三种 Go 时间布局常量):

写法格式说明示例
YYMMDD6 位紧凑格式171030(即 2017-10-30)
YYYY-MM-DDTHH:MM:SS秒级 ISO 风格,长度 192006-01-02T15:04:05
YYYY-MM-DDTHH:MM:SS.SSS纳秒级,允许小数秒2006-01-02T15:04:05.123456789

源码实现根据字符串长度自动选择解析布局:长度恰好为 19 时使用秒级布局,超过 19 时使用纳秒级布局(2006-01-02T15:04:05.999999999,末尾零会被自动裁掉),否则回退到 6 位的YYMMDD。这意味着你不能用小时精度的中间格式,例如2006-01-02这种不带时间成分的写法不会被接受。

时区注意:--timestamp的值默认按UTC解析。若你想按本地时区解释,需要追加--localtime。在代码层面体现为time.Parse(UTC)与time.ParseInLocation(layout, ts, time.Local)(本地时区)的分支选择。

2.--recursive/-R:递归批量更新时间

当remote:path指向一个目录时:

  • 不指定--recursive:只处理该目录自身层级下的对象(非递归);
  • 指定--recursive:递归遍历该目录下找到的全部已存在文件,逐个设置修改时间。

递归模式有几个重要的联动特性:

  • 绝不创建新文件:递归只对"已存在"的文件生效,隐含等价于--no-create;
  • 支持过滤器:--recursive生效时,rclone 的过滤器体系(--include/--exclude/--filter等)会自动应用到被遍历的文件集合上;
  • 试运行安全网:递归会成批修改远端对象,属于破坏性操作,因此官方文档明确建议先用--dry-run(空跑)或--interactive/-i(逐项交互确认)验证过滤与范围,再正式执行;
  • 并发控制:递归 touch 会按--transfers的取值并发处理文件(见下文源码分析)。

3.--no-create/-C:禁止创建新文件

行为对照如下:

  • 目标文件不存在且未加-C:创建一个零字节文件(唯一的例外是--recursive场景,此时不创建);
  • 目标文件不存在且加了-C:跳过,不创建、不报错,仅在日志中提示 "Not touching nonexistent file due to --no-create";
  • 目标文件存在:无论是否加-C都正常更新时间戳——-C只影响"创建"语义,不影响"更新"语义。

4.--localtime:本地时区解释时间戳

见上文--timestamp的时区说明:默认按 UTC 解析,加上--localtime后改用系统本地时区(time.Local)。

三、创建文件时写入元数据:--metadata-set

touch在创建新文件时支持携带元数据,命令形态为:

rclone touch remote:path -M --metadata-set key=value

逐段拆解:

  • -M是--metadata的简写,用于开启元数据处理能力(命令行开关定义见 configflags.go);
  • --metadata-set key=value声明要写入的键值对,这是一个可重复出现的参数,可通过多次传参写入多条元数据;
  • 底层解析逻辑位于 configflags.go 的 SetFlags 函数:每条必须以=分隔,缺失=会直接报错退出;键名会被统一转为小写后再存入ci.MetadataSet。

需要强调的是,元数据能否真正落盘取决于远端后端的能力:

  • 后端需具备用户元数据能力(fs/features.go中定义的ReadMetadata/WriteMetadata/UserMetadata等 Feature,见 features.go);
  • 例如本地文件系统、S3、对象存储等支持元数据的后端可以生效,而能力受限的后端会被跳过——对应测试 TestTouchWithMetadata 中if !features.UserMetadata { t.Skip(...) }的处理。

四、命令执行入口与核心流程(源码级拆解)

touch的命令逻辑集中在两个层次:cmd/touch/touch.go负责单文件与入口调度,fs/operations/operations.go提供目录递归实现。

1. 入口与时间计算

命令的Run回调(touch.go)严格校验参数必须恰好为 1 个(cmd.CheckArgs(1, 1, ...)),随后调用核心函数Touch。时间来源有两个分支(timeOfTouch):

  • 未提供--timestamp→time.Now();
  • 提供了--timestamp→ 按上一节的格式与时区规则解析,解析失败会返回failed to parse timestamp argument错误。

2. 三种路径状态的决策树

核心函数 Touch 的完整执行流程如下:

  1. 先尝试f.NewObject获取目标对象;路径为空(例如remote:本身)时直接按目录处理;
  2. 对象不存在(fs.ErrorObjectNotFound):
    • 路径为空目录 → 提示 "Not touching empty directory" 后结束;
    • 带--no-create→ 日志提示后结束;
    • 带--recursive→ 为保持一致性同样不创建,日志提示后结束;
    • 否则进入"创建"路径:先经过operations.SkipDestructive的干跑/交互检查,再调用 createEmptyObject——它通过object.NewStaticObjectInfo构造一个长度为 0 的静态对象,交给f.Put真正写入后端,并把这个静态对象的modTime设为 touch 时间;
  3. 对象是目录(fs.ErrorIsDir):按recursive布尔值进入operations.TouchDir;
  4. 对象存在且是普通文件:经SkipDestructive检查后调用file.SetModTime(ctx, t)直接更新时间戳。

3. 目录递归:并发 + 深度控制

目录场景最终落在 operations.TouchDir。它的关键实现要点是:

  • 通过walk.ListR遍历目录条目,并以ConfigMaxDepth控制深度;
  • 深度规则见 ConfigMaxDepth:非递归时最大深度强制为 1,递归时则放开为--max-depth(默认 -1,即不限深度);
  • 使用errgroup+g.SetLimit(ci.Transfers)实现并发:默认同时 touch 的文件数与--transfers一致(rclone 默认--transfers为 4),这与命令文档中 "This will touch--transfersfiles concurrently" 的描述完全对应;
  • 每个文件修改时间失败时调用fs.CountError计数并记录错误日志,全部完成后统一g.Wait()汇总。

4. 干跑与交互确认

创建与更新时间戳都属于破坏性写操作,统一经过 SkipDestructive 把关:

  • --dry-run被设置时,所有 touch 写操作一律跳过并输出日志 "Skipped ... as --dry-run is set";
  • --interactive(-i)被设置时,会弹出逐项确认,选择结果会被缓存复用(同一动作只询问一次);
  • 两者均未设置时才真正执行写操作。

五、常用共享参数

除touch自有参数外,本命令还与其他命令共享下列参数组(在命令帮助中touch被标记为属于 Filter、Listing、Important 三个选项组,见 touch.go 的 Annotations)。

1. Important 选项(通用关键参数)

参数简写含义
--dry-run-n试运行,不做任何永久性修改(在 touch 的递归批量场景中强烈推荐先用它验证范围)
--interactive-i开启交互模式,破坏性操作前逐项询问
--verbose-v输出更多日志,可重复使用(-vv进入调试级)

此外 rclone 还有大量不在本文展开的全局选项,可通过rclone help flags查看。

2. Filter 选项(递归 touch 的过滤器)

在--recursive遍历时,以下过滤参数可精确圈定要更新时间戳的文件集:

参数含义
--delete-excluded同步时删除被排除的 dest 文件(此处仅作语法继承说明)
--exclude stringArray/--exclude-from按模式排除文件 / 从文件(-表示 stdin)读取排除规则
--exclude-if-present若目录中存在指定文件名则排除该目录
--files-from/--files-from-raw/--files-from0从文件读源文件名清单(raw 不做行处理,0以 NUL 分隔)
--filter/--filter-from增加过滤规则 / 从文件读过滤规则
--hash-filter按文件名哈希k/n或随机@/n分区
--ignore-case过滤时忽略大小写
--include/--include-from按模式包含文件 / 从文件读取包含规则
--max-age/--min-age仅处理更年轻 / 更老于指定时长的文件(支持s/ms/m/h/d/w/M/y后缀)
--max-depth限制递归深度(默认 -1,不限)
--max-size/--min-size仅处理更小 / 更大尺寸的文件
--metadata-exclude(-from)/--metadata-filter(-from)/--metadata-include(-from)按元数据模式过滤

典型组合如"只把某目录下 30 天前的.log文件时间统一为指定时刻":

rclone touch --recursive --include "*.log" --min-age 30d \ --timestamp 20240101 --dry-run remote:logs/

3. Listing 选项(列目录相关,语法继承)

参数含义
--default-time Time当文件/目录修改时间未知时展示的时间(默认2000-01-01T00:00:00Z)
--fast-list若后端支持则使用递归列表,占用更多内存但事务更少

六、测试验证:这些行为都是有据可查的

cmd/touch/touch_test.go 中的用例逐一锁定了上述行为,可用于对照印证:

测试函数验证的行为
TestTouchOneFile对一个不存在的路径执行 touch,能创建出文件
TestTouchWithNoCreateFlag开启--no-create后不再创建新文件
TestTouchWithTimestamp/TestTouchWithLongerTimestampYYMMDD与完整秒级时间戳两种格式均能被正确解析并写入
TestTouchUpdateTimestamp对已存在文件 touch 只更新时间戳,内容保持不变(写入 "aaa" 后校验仍在)
TestTouchUpdateTimestampWithCFlag-C不影响已存在文件的更新时间戳
TestTouchCreateMultipleDirAndFiletouch 一个深层不存在的路径a/b/c.txt时,会自动创建中间目录a、a/b与空文件
TestTouchEmptyName/TestTouchEmptyDir空路径、空目录不会产生副作用
TestTouchDirWithFiles/TestRecursiveTouchDirWithFiles目录内(及递归深层)文件被批量处理
TestTouchWithMetadata元数据写入仅在支持UserMetadata的后端执行;测试通过ci.Metadata+ci.MetadataSet注入键值并回读校验

七、典型实战场景

综合上述全部行为,rclone touch的典型用途可归纳为三类:

  1. 占位 / 标记文件:在存储桶或网盘路径上快速放置零字节文件作为"标记"或"锁",例如

    rclone touch gdrive:backup/.in_progress
  2. 统一校准历史时间戳:迁移或对齐数据后,把某个子树所有文件时间批量归一到指定 UTC 时刻,先干跑后正式执行:

    rclone touch -R --timestamp 2025-06-01T00:00:00 --dry-run remote:photos/ rclone touch -R --timestamp 2025-06-01T00:00:00 remote:photos/
  3. 按过滤条件精准触碰:借助过滤器 +--interactive把修改范围缩小到特定后缀、特定年龄的文件,避免误伤:

    rclone touch -R -i --include "*.mp4" --min-size 100M remote:videos/

无论哪种场景,只要涉及递归或新建文件,都建议先用--dry-run/-i校验路径与过滤范围;在了解后端元数据能力的前提下,--metadata-set还能让空文件从创建之初就携带所需的键值标记。如果你需要对照其他命令文档,可参考 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),仅供参考

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

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

立即咨询