跳转到内容

附件

attachments 命令(别名 attachment、a)封装了 Redmine 的附件 API,让你既能查看附件的元数据,也能下载其字节内容。下载会复用当前 profile 的服务器地址和 API 密钥,并直接流式写入磁盘 - 无需 curl,也无需手动提取密钥。

终端窗口
redmine attachments get <id> [flags]

别名:show、view、metadata。通过 GET /attachments/:id.json 获取附件的 ID、文件名、大小、内容类型、描述、作者和创建时间。表格输出还会显示下载 URL(若存在);json 会返回所有字段,包括 content_url。

标志 描述
-o, --output 输出格式:table、json
终端窗口
redmine attachments get 42
终端窗口
redmine attachments download <id> [flags]

别名:dl、get-file。使用当前 profile 进行认证,将附件的原始字节流式写入磁盘(或 stdout)。响应是流式处理的,不会整体缓存在内存中,因此下载大文件也很安全。

标志 描述
-d, --dir 保存到的目录,使用附件的真实文件名(目录不存在时自动创建)
--path 精确的目标文件路径。使用 - 可流式输出到 stdout
--clobber 覆盖目标位置已存在的文件
--allow-hidden 允许使用服务器提供的、以 . 开头的文件名保存(适用于 --dir 或默认目标)
-o, --output 确认信息的格式:json 打印结果对象;否则向 stderr 写入一行可读信息

若不指定目标标志,文件会以 ./<文件名> 保存到当前目录。

除非传入 --clobber,下载永远不会覆盖已存在的文件。这一规则适用于 --path、--dir 以及默认的当前目录。未传入时,命令会在下载前报错并给出路径:

failed to download attachment 42: logo.png already exists; use --clobber to overwrite it

字节会先流式写入目标目录中的临时文件,下载完成后才移动到最终位置。因此:

  • 下载失败或被中断时,已有文件保持不变,目标位置也不会留下不完整的文件。按一次 Ctrl-C 会停止下载并删除临时文件;若进程被直接终止(第二次 Ctrl-C、kill -9),目标目录中可能残留一个隐藏的 .redmine-download-*.tmp 文件,可以放心删除。
  • 永远不会跟随目标位置上的符号链接。不加 --clobber 时,符号链接(即使是悬空链接)也算作已存在的文件;加上 --clobber 时,被替换的是链接本身,链接指向的文件保持不变。
  • 目标位置是目录时总是报错,即使加了 --clobber。其他非普通文件同样如此;唯一的例外是:--path 指向(或链接到)字符设备或命名管道(例如 /dev/null 或 FIFO)时,会直接写入,无需 --clobber。(当 stdout 是终端或管道时,/dev/stdout 也属于这种情况;要写到 stdout,建议使用 --path -。)使用 --dir 或默认目标时,这类条目会像目录一样被拒绝。
  • 新文件的权限与你创建的其他文件相同(在常见的 umask 022 下为 0644)。使用 --clobber 替换普通文件时,会保留其原有权限。

不加 --clobber 时,最后一步使用硬链接;如果下载期间目标位置出现了文件,该操作会原子地失败。在不支持硬链接的文件系统上,CLI 会退回到先重新检查目标位置、再重命名的方式,检查与重命名之间存在一个很小的时间窗口。

使用 --dir 或默认目标时,文件名来自服务器。文件名会被缩减为其基本名称,因此永远无法逃逸出目标目录。以 . 开头的文件名(例如 .bashrc、.envrc 或 .npmrc)可能会植入或遮蔽配置文件,因此会被拒绝,除非传入 --allow-hidden:

failed to download attachment 42: refusing to save the hidden filename ".bashrc" as downloads/.bashrc; pass --allow-hidden to save it anyway

用 --path 自行指定文件名不受此限制,--path -(stdout)同样不受影响。

如果服务器对下载(或任何其他请求)进行重定向,只有当重定向留在配置的服务器上(相同的主机和端口,或从 http:// 服务器升级到 https://,端口 80 变为 443),或指向公网地址(例如 S3 等对象存储的预签名 URL)时,才会跟随该重定向。凭据只会发送到配置的服务器,绝不会发送到重定向目标。从 https:// 到 http:// 的重定向,以及指向回环、私有、链路本地、组播、未指定(0.0.0.0/8)、运营商级 NAT(100.64.0.0/10)或基准测试(198.18.0.0/15)地址的重定向都会被拒绝,包括内嵌上述地址的 IPv6 地址(IPv4 映射、NAT64 64:ff9b::/96、6to4 2002::/16);主机名会针对实际连接的地址重新检查。当重定向经过 HTTP(S) 代理时,CLI 自身不会连接目标,因此它会在本地解析主机名,如果解析结果指向上述地址之一则拒绝;只有代理能解析的名称交由代理处理。配置的服务器主机上的其他端口与任何其他主机接受相同的检查。指向公网 http:// URL 的重定向会被跟随,只要它不是来自 https:// URL。

终端窗口
# 保存为 ./<文件名>
redmine attachments download 42