首页
/ rclone mkdir 命令详解:一条命令在任意远端存储上创建目录

rclone mkdir 命令详解:一条命令在任意远端存储上创建目录

2026-09-07 10:04:43作者:霍妲思

rclone mkdir remote:path 是 rclone 中最基础也最常用的目录创建命令,其作用一句话即可概括:Make the path if it doesn't already exist(如果路径尚不存在,则创建它)。本文以 docs/content/commands/rclone_mkdir.md 为骨架,结合 rclone 源码(cmd/mkdir/fs/operations/)逐一拆解该命令的用法、全部选项、底层执行链路,以及本地磁盘、S3 等不同存储后端在"创建目录"上的语义差异。读完本文,你将能在任意 rclone remote 上准确、安全地创建目录,并理解为什么个别后端上 mkdir 可能"什么都不做"。

命令概览与基本用法

rclone mkdir 接受且只接受一个参数:以 remote: 前缀开头的目标路径,目标 remote 必须已经通过 rclone config 完成配置。命令的标准形式如下:

rclone mkdir remote:path [flags]

mkdir 被列入 rclone 的 Important(重要命令) 分组。从 cmd/mkdir/mkdir.go 的源码可以看到,命令通过 cobra 注册、严格校验参数个数:

Use:   "mkdir remote:path",
Short: `Make the path if it doesn't already exist.`,
Annotations: map[string]string{
    "groups": "Important",
},
Run: func(command *cobra.Command, args []string) {
    cmd.CheckArgs(1, 1, command, args)          // 只允许恰好 1 个位置参数
    fdst := cmd.NewFsDir(args)                   // 把 remote:path 解析为 fs.Fs
    ...
    cmd.Run(true, false, command, func() error {
        return operations.Mkdir(context.Background(), fdst, "")
    })
},
  • cmd.CheckArgs(1, 1, ...) 意味着传 0 个或 2 个以上的路径都会直接报错退出;
  • 参数中的路径会被解析成目标 fs.Fs 对象(其根目录就是要创建的路径);
  • 最终真正执行的是 operations.Mkdir

最小可用示例

# 在本机创建目录
rclone mkdir /tmp/rclone-demo/subdir

# 在 Google Drive 上创建目录
rclone mkdir gdrive:文档/2026

# 在 S3 兼容存储上创建目录(会同时确保 bucket 存在并写入目录标记)
rclone mkdir s3:mybucket/data/raw

目录路径中的多级嵌套(例如 文档/2026)由各后端自行递归处理,详见下文"后端语义"部分。

幂等语义:目录已存在不是错误

命令帮助文本刻意使用 "if it doesn't already exist" 来描述行为,这是 mkdirsync/copy 等命令共用同一套"目录不敏感"哲学的体现:当目标目录已经存在时,rclone mkdir 不会报错,也不会覆盖或修改已有内容,只是静默完成。因此 mkdir 非常适合出现在自动化脚本中作为"确保目录就绪"的前置步骤,例如:

#!/bin/bash
rclone mkdir backup:snapshots/$(date +%Y/%m)
rclone copy ./data backup:snapshots/$(date +%Y/%m)/

选项解析

rclone mkdir 本身只有一个专属标志,其余为所有命令共享的通用选项。命令的 Options 部分原文如下:

-h, --help   help for mkdir

而在 Important Options(对大多数命令都实用的一组重要标志)中,声明了三个最重要的通用开关:

-n, --dry-run         Do a trial run with no permanent changes
-i, --interactive     Enable interactive mode
-v, --verbose count   Print lots more stuff (repeat for more)

它们的含义与使用要点整理如下:

选项 缩写 类型 作用 使用建议
--help -h bool 打印该命令的帮助信息 忘记参数时随时查看
--dry-run -n bool 只做预演,不产生任何持久化修改 批量操作前先用它确认将要执行的动作
--interactive -i bool 启用交互模式,执行破坏性操作前逐条征询确认 配合 --dry-run 一起用来人肉审核
--verbose -v count 输出更多调试信息,可重复叠加提高详细程度 -vv 查看传输细节,排查故障时使用

由于 mkdir 本质上是幂等且非破坏性的,--dry-run / --interactive 对它的实际约束能力有限(目录已存在则无事可做),但它们与所有 rclone 命令保持一致的语法和语义,方便你在同一组脚本里统一使用。这两个开关在 docs/content/flags.mddocs/content/commands/rclone.md 中有全量说明。不属于本页 Important Options 的其他全局标志(如并发数、日志级别、带宽限制等)统称为 global flags,可查阅 docs/content/flags.md

常用组合示例

# 预演:看 mkdir 会执行什么(不会真正创建)
rclone mkdir -n -vv gdrive:文档/2026

# 交互式执行
rclone mkdir -i gdrive:文档/2026

# 完整、冗余日志输出
rclone mkdir -v -v s3:mybucket/data/raw

底层执行链路:从 CLI 到 operations.Mkdir

理解一条 rclone mkdir 命令真正做了什么,需要顺着源码调用链往下看。核心链路为:

  1. 参数解析cmd/mkdir/mkdir.gocmd.NewFsDir(args) 负责把 remote:path 字符串解析并缓存为一个 fs.Fs 接口对象(其 Root() 即为目标路径)。
  2. 目录创建:随后调用 fs/operations/operations.go 中的 operations.Mkdir
// Mkdir makes a destination directory or container
func Mkdir(ctx context.Context, f fs.Fs, dir string) error {
    if SkipDestructive(ctx, fs.LogDirName(f, dir), "make directory") {
        return nil
    }
    fs.Infof(fs.LogDirName(f, dir), "Making directory")
    err := f.Mkdir(ctx, dir)
    if err != nil {
        err = fs.CountError(ctx, err)
        return err
    }
    return nil
}

从这里可以读出三个细节:

  • SkipDestructive 对应 --dry-run / --interactive 的拦截逻辑,若被跳过则直接返回 nil;
  • 创建前后分别输出 Making directory(Info 级别)日志,便于用 -v 观察;
  • 失败的错误会计入全局错误统计(fs.CountError),从而影响进程退出码与最终汇总。
  1. 后端实现operations.Mkdir 最终调用接口方法 f.Mkdir(ctx, dir)Mkdir 是 rclone 后端统一抽象 fs.Fs 接口的一部分,在 fs/types.go 中有明确声明:
type Fs interface {
    ...
    Mkdir(ctx context.Context, dir string) error   // 创建容器或目录
    ...
}

也就是说,每条 mkdir 的实际"手艺"都交给具体的存储后端实现,而不同后端对"目录"的建模差异很大(见下节)。

不同后端上的目录语义与空目录警告

rclone 要同时对接"真目录"式存储(本地磁盘、SFTP、Google Drive)与"对象桶"式存储(S3、Swift、Azure Blob 等),因此它对目录的处理是可插拔的,由后端在特性结构中声明:

// Features describe the optional features of the Fs
type Features struct {
    ...
    CanHaveEmptyDirectories  bool // can have empty directories
    BucketBased              bool // is bucket based (like s3, swift, etc.)
    ...
}

(定义见 fs/features.go

支持空目录的后端

以本地文件系统为例,backend/local/local.goMkdir 直接调用操作系统的递归建目录能力,支持任意深度的空目录,声明 CanHaveEmptyDirectories: true(见同文件第 473 行附近):

func (f *Fs) Mkdir(ctx context.Context, dir string) error {
    localPath, err := f.localPath(dir)
    ...
    err = f.mkdirAll(localPath)
    ...
    return nil
}

绝大多数有层级目录概念的后端(如 backend/archive/archive.gobackend/box/box.gobackend/dropbox/dropbox.gobackend/sftp/sftp.go 等)都声明了 CanHaveEmptyDirectories: true

仅以对象模拟目录的后端(空目录警告的由来)

部分对象存储后端没有"空目录"这一概念,所谓目录不过是以 / 结尾的占位对象。典型例子是 S3 的 Mkdir 实现(backend/s3/s3.go):

// Mkdir creates the bucket if it doesn't exist
func (f *Fs) Mkdir(ctx context.Context, dir string) error {
    bucket, _ := f.split(dir)
    e := f.makeBucket(ctx, bucket)
    if e != nil {
        return e
    }
    return f.createDirectoryMarker(ctx, bucket, dir)
}

它先确保 bucket 存在,再写入一个零字节的目录标记对象。

正因为存在这类后端,cmd/mkdir/mkdir.go 里加入了一段保护性提示:当目标后端声明不支持空目录(CanHaveEmptyDirectories == false)且路径中带有 / 时,命令会打印警告,说明 mkdir 在该后端上不会产生有意义的持久化结果:

if !fdst.Features().CanHaveEmptyDirectories && strings.Contains(fdst.Root(), "/") {
    fs.Logf(fdst, "Warning: running mkdir on a remote which can't have empty directories does nothing")
}

因此:对这类远端,空目录本身通常无法独立存在——当你之后把文件传入该目录时目录才会被真正"物化"。如果在某个 object-storage 后端执行 mkdir 时看到该警告,属于正常现象而非命令故障;你仍可继续正常上传文件。

为何其他命令不需要预先 mkdir

rclone 的 synccopymove 等命令在写入对象前都会自动确保目标目录存在(例如 S3 后端通过 mkdirParent 在写入前置空目录标记),所以日常场景中你并不需要先手动 mkdirrclone mkdir 真正的典型用途是:

  • 为后续上传预创建一个可被其他工具/人员感知的目录占位;
  • 在支持空目录的后端(Drive、本地、SFTP、Dropbox 等)上创建"纯目录骨架";
  • 让脚本在不知道目标目录是否已存在时安全地保证"目录就绪"。

验证创建结果

创建完成后,用下列命令确认目录确实存在:

# 列出目录下的内容(空目录输出为空)
rclone lsd gdrive:文档/2026

# JSON 形式列出,便于脚本解析
rclone lsjson gdrive:文档/2026

# 对本地磁盘也可以直接用系统命令确认
ls -ld /tmp/rclone-demo/subdir

若需要反向操作,可配合 cmd/rmdir/rmdir.gorclone rmdir,仅删除空目录)或 rclone rmdirs(递归删除空目录树)使用。

小结

rclone mkdir remote:path 是一枚简单、幂等、可放心重复执行的目录创建命令:

  • 严格接受单一路径参数,通过 cmd/mkdir/mkdir.go 中的 cmd.CheckArgs(1, 1, ...) 校验;
  • 支持 --help--dry-run--interactive--verbose 等通用选项;
  • 真正执行时经 fs/operations/operations.gooperations.Mkdir 落到后端 Fs.Mkdir 接口(fs/types.go);
  • 目录已存在时不做任何事,脚本里可以放心用作"确保就绪"的步骤;
  • 对不支持空目录的对象存储后端,mkdir 可能只起占位作用,此时命令行会给出明确警告。

掌握了这条命令的选项与后端语义,你就能在不同存储之间以统一、可预期的方式管理目录结构,为 copysyncmove 等操作铺平路径。

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