rclone Shade 后端完全指南:AI 云 NAS 的配置、多段上传与已知限制解析
Shade 是 rclone 官方支持的云存储后端之一,对应 shade(Shade FS)类型,可让 rclone 像访问本地磁盘一样读写 Shade 这一 AI 驱动的云 NAS 服务。本文以 backend/shade 后端文档 为骨架,结合 shade.go、upload.go 等源码实现,系统讲解如何创建 Shade 远程、完整配置全部选项、理解其 JWT 鉴权与多段上传机制,并梳理其哈希、删除、大小写敏感等边界限制。读完你可以独立在 rclone 中接入 Shade 云盘,并清楚哪些工作流(如挂载、union 联合远程)会受到该后端能力边界的约束。
Shade 后端是什么
Shade 是一个 AI 驱动的云 NAS 平台,定位是"让云文件像本地磁盘一样工作",针对媒体与创意工作流进行了优化,提供自然语言搜索、便捷分享与可扩展的云存储能力。rclone 通过 shade 后端与 Shade FS 文件接口通信,将云端内容映射为标准文件系统的目录树。
该后端于 v1.73 版本引入(见 文档 Front matter),当前注册在 backend/all/all.go#L62 的 _ "github.com/rclone/rclone/backend/shade" 中,因此只要编译进该导入即可被 rclone config 枚举到,官方文档亦将其列于 docs/content/docs.md 的后端清单中。
从源码结构看,后端采用分层设计:
- backend/shade/shade.go:实现
fs.Fs、fs.Object、fs.Directory接口及注册信息,是核心文件; - backend/shade/upload.go:封装多段上传(multipart upload)的发起、分片写入、完成与中止;
- backend/shade/api/types.go:定义与 Shade API 交互的数据结构。
两个客户端分别指向两个服务域(shade.go#L34-L38):ShadeFS 文件接口默认端点为 https://fs.shade.inc,而获取令牌的 API 端点为 https://api.shade.inc,两者通过 rest.Client 与内建 pacer(限速与重试器)驱动。
使用前提:账户、API Key 与 Drive ID
使用该后端前需要有一个 Shade 账户并选择一个套餐。可以注册免费账户,免费档包含 20GB 存储空间。
需要从账户的 settings 区域取得两项关键凭据:
- API Key:账户级密钥,用于换取后端实际使用的访问令牌;
- Drive ID:某个具体云盘(drive)的 ID,可在该 drive 的设置中查看。
需要注意:每个 drive 必须单独建立一份 rclone 配置,drive_id 不能跨 drive 复用(见 shade.go#L73 对 drive_id 选项的说明)。
路径语法
与 rclone 其它远程一致,Shade 远程通过 remote:path 形式引用:
remote:directory/subdirectory
路径可以按需嵌套任意层级;远程下的子目录与文件都以此格式拼接访问。
创建远程:交互式配置流程
创建远程使用标准命令:
rclone config
按提示选择 n(new remote),在类型列表中选择 Shade FS(即 shade),随后依次输入 drive_id 与 api_key。完整交互过程如下:
$ rclone config
e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q> n
Enter name for new remote.
name> Shade
Option Storage.
Type of storage to configure.
Choose a number from below, or type in your own value.
[OTHER OPTIONS]
xx / Shade FS
\ (shade)
[OTHER OPTIONS]
Storage> xx
Option drive_id.
The ID of your drive, see this in the drive settings. Individual rclone configs must be made per drive.
Enter a value.
drive_id> [YOUR_ID]
Option api_key.
An API key for your account.
Enter a value.
api_key> [YOUR_API_KEY]
Edit advanced config?
y) Yes
n) No (default)
y/n> n
Configuration complete.
Options:
- type: shade
- drive_id: [YOUR_ID]
- api_key: [YOUR_API_KEY]
Keep this "Shade" remote?
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y
建立远程后即可用 rclone ls Shade:, rclone copy file.jpg Shade:photos/ 等常规命令操作。创建远程时 rclone 会立刻尝试换取令牌做一次登录校验:NewFS 会调用 refreshJWTToken 并请求 /fs/attr 验证凭据是否有效(shade.go#L495-L509),因此凭据错误在配置阶段就会被发现。
全部配置选项
标准选项(Standard options)
| 选项 | Config 键 | 环境变量 | 类型 | 必填 | 说明 |
|---|---|---|---|---|---|
--shade-drive-id |
drive_id |
RCLONE_SHADE_DRIVE_ID |
string | 是 | 在 drive 设置中查看的云盘 ID;每个 drive 需单独配置 |
--shade-api-key |
api_key |
RCLONE_SHADE_API_KEY |
string | 是 | 账户的 API 密钥 |
这两个选项除交互式填写外,也可以直接以命令行参数或环境变量方式传入。
高级选项(Advanced options)
高级选项在交互式配置中选择 y(Edit advanced config)后可见,也可在配置文件中手工写入或通过命令行覆盖:
| 选项 | Config 键 | 环境变量 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|---|
--shade-endpoint |
endpoint |
RCLONE_SHADE_ENDPOINT |
string | 空 | 服务端点,一般留空使用默认值 https://fs.shade.inc |
--shade-chunk-size |
chunk_size |
RCLONE_SHADE_CHUNK_SIZE |
SizeSuffix | 64Mi |
上传分块大小,最小 5MB,最大 5GB |
--shade-upload-concurrency |
upload_concurrency |
RCLONE_SHADE_UPLOAD_CONCURRENCY |
int | 4 |
同一个文件并发上传/拷贝的分块数 |
--shade-max-upload-parts |
max_upload_parts |
RCLONE_SHADE_MAX_UPLOAD_PARTS |
int | 10000 |
单次多段上传允许的最大分块数 |
--shade-token |
token |
RCLONE_SHADE_TOKEN |
string | 空 | 用于 Shade FS 操作的 JWT 令牌,不要手动设置,rclone 会自动写入 |
--shade-token-expiry |
token_expiry |
RCLONE_SHADE_TOKEN_EXPIRY |
string | 空 | JWT 令牌过期时间,同样由 rclone 自动维护 |
--shade-encoding |
encoding |
RCLONE_SHADE_ENCODING |
Encoding | Slash,BackSlash,Del,Ctl,InvalidUtf8,Dot |
后端文件名字符编码策略 |
--shade-description |
description |
RCLONE_SHADE_DESCRIPTION |
string | 空 | 远程描述信息 |
逐项说明:
endpoint:默认留空,rclone 在 NewFS 中检测到为空即回落至编译期常量 defaultEndpoint(https://fs.shade.inc),详见 shade.go#L476-L481。
chunk_size:决定大于该尺寸的文件如何被切块上传。该值按每次传输保存在内存中,因此调大它意味着更高的内存占用。源码还给出了硬性边界校验:minChunkSize = 5MB、maxChunkSize = 5GB,超出范围会在创建远程时直接报错(shade.go#L40-L42、shade.go#L483-L490)。
upload_concurrency:同一个文件的多段上传与拷贝中,并发上传的分块数量。加大并发会缩短大文件上传耗时,但会占用更多内存并产生更多 HTTP 请求。
max_upload_parts:多段上传的最大分块数。代码中常量上限同样是 10000(shade.go#L43),OpenChunkWriter 会把配置值钳制在 [1, 10000] 区间(upload.go#L63-L68)。
token / token_expiry:这两个值是 rclone 自动获取并回写配置的,不应手工设置。它们的存在使得新进程可直接复用上次的令牌,避免每次都向 API 重新换取。
encoding:决定后端对特殊文件名字符的编码方式,默认组合等价于源码中的 Display | EncodeBackSlash | EncodeInvalidUtf8(shade.go#L111-L116)。详细的编码规则说明可参阅 文档 overview 的 encoding 章节。
自动化的 JWT 令牌刷新机制
Shade 后端的文件操作并不直接使用 API Key,而是通过 API Key 换取有效期受限的 JWT 令牌。理解这一点有助于排查"凭据正确却偶发 401"的现象。
refreshJWTToken(shade.go#L122-L203)的实现要点:
- 若本地已有令牌且距
exp过期时间仍有 2 分钟以上余量,直接复用(checkTime := f.tokenExp.Add(-2 * time.Minute)); - 否则向
https://api.shade.inc/workspaces/drives/{drive_id}/shade-fs-token发起 GET,并在Authorization头中携带 API Key; - 响应体即令牌本身(纯文本);rclone 解析其 JWT payload(对
.分隔的第二段做base64.RawURLEncoding解码)提取exp声明,得到确切过期时刻; - 新令牌会被同时写回配置映射,持久化为
token与token_expiry两个配置项,供后续进程复用; - 对 429/500/502/503/504/509 等状态码及网络类错误走 pacer 重试策略(重试码列表见 shade.go#L47-L54)。
所有后续文件操作都会先经此函数确保拿到有效令牌,再以 Authorization: Bearer <token> 访问 /fs/* 接口,或先经 /fs/download 获取带签名重定向地址后再拉取对象内容(见 shade.go#L836-L947 中对 307 Temporary Redirect 返回预签名 URL 的处理)。
传输机制:默认使用多段上传
Shade 后端默认以多段(multipart)方式上传文件,即大于分块阈值的文件会被切成若干块、以并发方式分别上传,最后合并为完整对象。对应分块大小由 chunk_size 决定,并发度由 upload_concurrency 控制。
从 upload.go 可以还原完整的四阶段流程:
- 发起(Initiate):
OpenChunkWriter向/upload/multipartPOST 文件路径与partSize,得到本次上传的initToken(upload.go#L102-L148); - 写块(WriteChunk):对每个分块先向
/upload/multipart/part/{n}?token=...申请一个带可选请求头的预签名 PUT 地址,再把整块字节经 pacer 重试后 PUT 上去,并记录响应中的ETag(upload.go#L151-L231); - 完成(Close):将已成功上传的 Part 列表按 PartNumber 排序后 POST 到
/upload/multipart/complete(upload.go#L234-L278); - 中止(Abort):出错时调用
/upload/abort/multipart清理未完成的上传,且该操作不重试(upload.go#L283-L313)。
实现采用 rclone 通用 multipart.UploadMultipart 封装与 ChunkWriter 抽象,每块大小由 chunksize.Calculator 依据文件总大小、剩余可用的分块数与 chunk_size 动态调整(upload.go#L69-L85)。
值得注意的流式上传场景:当文件大小未知(size == -1)时,会按配置的 chunk_size(默认 64MB)缓冲,此时理论上限为 chunk_size × max_upload_parts,即默认约 640GB(64MB × 10000);触发时 rclone 会打印对应提示日志(upload.go#L75-L82)。
修改时间与哈希
- 哈希:Shade 不支持任何校验哈希。
Fs.Hashes()返回空集合(shade.go#L423-L426),Object.Hash直接返回hash.ErrUnsupported(shade.go#L810-L813)。因此rclone check、rclone dedupe等依赖哈希的比对将退化为仅按大小比较或不可用。 - 修改时间:Shade 不支持写入修改时间,
Precision()返回fs.ModTimeNotSupported(shade.go#L295-L298),SetModTime返回fs.ErrorCantSetModTime(shade.go#L825-L829)。对象自带的mtime(毫秒级时间戳)仅在列出、属性查询时被读取返回(见 api/types.go#L10 的Mtime字段)。
在文档中分别说明为:Shade does not support hashes and writing mod times。
删除行为:即时删除而非回收站
在 Shade 上通过 rclone 删除文件时会立即彻底删除,而不是移入回收站/垃圾桶。这意味着删除操作不可恢复,执行 rclone delete、rclone purge 或后端相关删除命令前应格外谨慎。
底层实现上,文件对象删除直接 POST /fs/delete?path=...(shade.go#L975-L989);目录删除 Rmdir 会先列出目录内容,仅当目录为空时才调用同一删除接口,非空目录返回 fs.ErrorDirectoryNotEmpty(shade.go#L736-L778)。DirMove/Move 则通过 /fs/move 走服务端移动(shade.go#L309-L421),并在移动目录前确保父目录存在。
限制与注意事项
使用 Shade 后端前应了解以下由服务特性带来的限制:
- 大小写不敏感:Shade 文件系统不区分大小写,因此不能同时存在名为
Hello.doc与hello.doc的文件,同步这类冲突时会引发错误。 - 文件名长度上限 255 字符:超出该长度的文件名无法正常存取。
- 不支持
rclone about:Fs没有提供用量查询能力。这带来的连锁影响是:- rclone mount 挂载时无法得知剩余可用空间;
- 作为 union 联合远程成员时,不能使用
mfs(most free space,最大剩余空间)策略。
about 支持属于 rclone 的可选特性之一,关于不支持该特性的后端完整清单可查看文档,rclone about 命令本身的用法见 rclone_about 命令文档。
后端专用命令
与大多数 rclone 后端类似,shade 后端相关的专用命令(若有)通过如下语法运行:
rclone backend COMMAND remote:
关于如何向 backend 命令传参的通用说明见 rclone backend 命令文档。这些命令也可以在运行中的后端上通过 rc 接口的 backend/command 调用,参见 rc.md 的 backend/command 章节。截至当前仓库版本,shade 后端尚未在 shade.go 中注册任何额外自定义命令,因此该机制更多是为后续服务端能力(如按需生成分享链接、配额管理等)预留的扩展点。
集成测试与验证方式
后端随仓库带有集成测试 backend/shade/shade_test.go:TestIntegration 复用 rclone 标准化的 fstests 测试框架,面向名为 TestShade 的远程执行全功能矩阵测试,并显式声明该后端为"最终一致"(eventually_consistent_delay 设为 7 秒,即测试需要容忍列表/属性结果最多约 7 秒的传播延迟)。该配置也提示实际使用中:文件刚写入后立即读目录,可能短暂看不到最新状态。
本地复现该测试需先在 rclone 配置中建立名为 TestShade 的 shade 远程(含有效的 drive_id 与 api_key),然后在仓库根目录执行:
go test ./backend/shade/ -run TestIntegration
小结
shade 后端把 AI 云 NAS 的能力封装成了标准的 rclone 远程,接入成本很低:只需账户的 API Key 与 Drive ID,一条 rclone config 即可完成。需要重点掌握的行为包括:JWT 令牌自动换取与提前 2 分钟续期的机制、默认 64MB 分块 × 4 并发且可在 chunk_size/upload_concurrency/max_upload_parts 间权衡的多段上传、不支持哈希与修改时间写入、删除即不可恢复,以及大小写不敏感、文件名 255 字符、无 rclone about 三条硬性限制——这些边界决定了它在挂载、union 组合与增量比对类工作流中的适用程度,规划数据迁移前建议先对照 官方后端文档 与本文的参数表核对需求。
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 StartedRust0629
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证件照制作算法。Python07
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