AWS S3 命令详解:cp、sync、ls、rm 示例

通过 Web 控制台向 Amazon S3 上传文件,偶尔做一次还行。但到了第十次,或者当你第一次需要移动整棵目录树时,你就会希望把它写进 shell 历史里。aws s3 命令组为 S3 提供了你熟悉的 Unix 风格操作:用 ls 列出、cp 复制、sync 镜像目录、rm 删除。

本指南给出最常用 aws s3 命令的实用示例,包括递归复制、include 与 exclude 过滤,以及用 --dryrun 安全删除。

前置条件

这些示例需要 AWS CLI 第 2 版,以及一个有权限访问你所使用 S3 资源的身份。如果 CLI 尚未就绪,请参考我们关于在 Linux 上安装和配置 AWS CLI 的指南。

用以下命令确认 CLI 能够向你的账户认证:

aws sts get-caller-identity

如果命令打印出你的账户 ID 和 IAM 身份,说明认证正常。即便如此,当该身份缺少所需的存储桶或对象权限时,单个 S3 命令仍可能返回 AccessDenied。

AWS CLI 有两个用于 S3 的命令组。本指南使用的 aws s3 组提供高级文件操作。aws s3api 组则暴露原始 API,每次调用一个操作,仅在你需要管理存储桶策略或对象版本等任务时才需要。

S3 路径的形式为 s3://bucket-name/key。通用命令结构如下:

aws s3 <subcommand> [ARGUMENTS] [OPTIONS]

像 cp、mv 和 sync 这样的命令接收源和目标参数。其余命令作用于单个 S3 路径,但 aws s3 ls 例外——它可以省略路径以列出每一个存储桶。

列出存储桶与对象

运行不带参数的 aws s3 ls 以列出账户中的所有存储桶:

aws s3 ls
2025-11-04 09:12:33 my-bucket
2026-01-15 17:40:21 my-site-backups

要列出某个存储桶的内容,传入存储桶路径:

aws s3 ls s3://my-bucket
                           PRE logs/
2026-02-10 08:30:12    1048576 backup.tar.gz
2026-02-11 09:02:44       4523 notes.txt

带有 PRE 标记的条目是前缀(prefix),即 S3 中等同于目录的概念。要查看其内部,在路径后追加斜杠,例如 aws s3 ls s3://my-bucket/logs/。

加上 --recursive 遍历整个存储桶,并配合 --human-readable 和 --summarize 获得易读的大小与总计:

aws s3 ls s3://my-bucket --recursive --human-readable --summarize
2026-02-10 08:30:12    1.0 MiB backup.tar.gz
2026-02-11 09:02:44    4.4 KiB notes.txt
2026-02-12 06:15:09   12.7 MiB logs/app.log

Total Objects: 3
   Total Size: 13.7 MiB

底部的摘要显示在当前存储桶或前缀下列出的对象的数量与合计大小。它不包含版本化存储桶中的非当前版本。

用 cp 上传和下载文件

cp 子命令在你的机器与 S3 之间双向复制文件。要上传文件到存储桶:

aws s3 cp backup.tar.gz s3://my-bucket/
upload: ./backup.tar.gz to s3://my-bucket/backup.tar.gz

对象保留其原始名称。要以不同的键存储,写出完整的目标路径:

aws s3 cp backup.tar.gz s3://my-bucket/backups/backup-2026-02-10.tar.gz

下载只需反转参数。. 目标将文件保存到当前目录:

aws s3 cp s3://my-bucket/backup.tar.gz .

你也可以直接在两个存储桶之间复制。传输在 AWS 内部进行,数据不会经过你的机器:

aws s3 cp s3://my-bucket/backup.tar.gz s3://my-site-backups/backup.tar.gz

复制目录

要复制一个目录及其下所有内容,加上 --recursive:

aws s3 cp ./logs s3://my-bucket/logs --recursive

当你只想要其中部分文件时,组合 --exclude 和 --include。过滤器按给定顺序求值,后面的过滤器胜出,因此通常的模式是先排除全部,再包含你想要的:

aws s3 cp ./logs s3://my-bucket/logs --recursive --exclude "*" --include "*.log"

这只会上传 .log 文件,跳过目录中的其他内容。

最有用的 cp 选项:

- --recursive - 复制目录或前缀下的所有文件。
- --exclude / --include - 按模式过滤文件;后面的过滤器覆盖前面的。
- --storage-class - 选择目标存储类别,例如用于不常访问备份的 STANDARD_IA。
- --dryrun - 打印将要复制的内容而不传输任何数据。

向 S3 流式传输

cp 命令接受 - 作为标准输入或输出的占位符,让你可以不经过临时文件直接将数据管道传输到存储桶:

pg_dump mydb | gzip | aws s3 cp - s3://my-bucket/backups/mydb.sql.gz

反向读取同理。这会将对象打印到标准输出,你可以进一步管道处理:

aws s3 cp s3://my-bucket/backups/mydb.sql.gz - | gunzip | head

用 mv 移动和重命名对象

Amazon S3 不会就地重命名对象。mv 命令先将源复制到新键,然后删除源,因此在运行前先预览操作:

aws s3 mv s3://my-bucket/report-draft.pdf s3://my-bucket/report-final.pdf --dryrun

仔细检查两条路径,然后去掉 --dryrun 再运行命令。同一命令可在你的机器与 S3 之间,或两个存储桶之间移动文件。

用 sync 同步目录

cp --recursive 每次都复制所有文件,而 sync 只传输缺失、大小不同或源修改时间更新的文件。要将本地目录镜像到存储桶:

aws s3 sync ./website s3://my-bucket/website

立即再次运行,什么都不会传输,因为两边已经匹配。这使 sync 成为重复任务(如发布静态站点或发送夜间备份)的正确工具。

反向方向从存储桶下载新增和变更的对象:

aws s3 sync s3://my-bucket/website ./website

在两个存储桶之间同步也可以:aws s3 sync s3://my-bucket s3://my-site-backups。

默认情况下,sync 从不删除任何内容。从源中删除的文件仍保留在目标上。要使目标成为精确镜像,加上 --delete,但先预览结果,因为被删除的对象将永久消失:

aws s3 sync ./website s3://my-bucket/website --delete --dryrun
(dryrun) upload: website/index.html to s3://my-bucket/website/index.html
(dryrun) delete: s3://my-bucket/website/old-page.html

每行都以 (dryrun) 为前缀,所以尚未发生任何事情。检查 delete: 行,当计划看起来正确时,去掉 --dryrun 运行相同命令。

cp 的相同 --exclude 和 --include 过滤器也适用于此处。一个常见做法是将仓库元数据排除在存储桶之外:

aws s3 sync ./website s3://my-bucket/website --exclude ".git/*"

由于 sync 是幂等的,它与计划任务配合良好。如果你想每晚运行一次 sync,请参阅我们关于使用 crontab 调度 cron 任务的指南。

用 rm 删除对象

要删除单个对象,传入其完整路径:

aws s3 rm s3://my-bucket/old-backup.tar.gz
delete: s3://my-bucket/old-backup.tar.gz

警告:S3 中没有回收站。除非存储桶启用了版本控制,否则删除的对象无法恢复。始终先用 --dryrun 测试递归删除。

要删除前缀下的所有内容,加上 --recursive 并在提交前预览损害:

aws s3 rm s3://my-bucket/logs/ --recursive --dryrun

如果列出的对象正是你期望的,去掉 --dryrun 再次运行命令执行删除。

在启用版本控制的存储桶上,rm 只插入删除标记;以前的版本仍然保留并继续产生存储成本。要永久删除版本,需要带版本 ID 的 aws s3api delete-object 调用。

创建和删除存储桶

mb(make bucket)子命令创建新存储桶。通用存储桶名称在 AWS 分区内的所有 AWS 账户和区域中必须唯一,因此请选择不易冲突的名称:

aws s3 mb s3://my-unique-bucket-name --region eu-central-1

rb(remove bucket)子命令删除存储桶,但仅当它为空时:

aws s3 rb s3://my-unique-bucket-name

加上 --force 会删除非版本化存储桶中的当前对象,然后移除存储桶。它不会永久删除对象版本或删除标记,因此当版本化存储桶仍包含它们时,删除会失败。请像对待 rm --recursive 一样谨慎对待 --force。

生成临时下载链接

有时你需要把文件交给某人,而不想让存储桶公开。presign 子命令生成一个授予对单个对象临时访问权限的 URL:

aws s3 presign s3://my-bucket/report.pdf --expires-in 3600

该命令打印一个长 URL,任何人都可以在接下来的一小时(3600 秒)内用它下载对象。默认有效期为一小时,最长为七天。用临时凭证签名的 URL 会在这些凭证过期时失效,即使 --expires-in 请求更晚的时间。

快速参考

对于可打印的快速参考,请参阅 AWS CLI 速查表。

任务 命令
列出所有存储桶aws s3 ls
列出存储桶内容aws s3 ls s3://bucket
递归列出含总计aws s3 ls s3://bucket --recursive --summarize
上传文件aws s3 cp file.txt s3://bucket/
下载文件aws s3 cp s3://bucket/file.txt .
上传目录aws s3 cp ./dir s3://bucket/dir --recursive
预览重命名对象aws s3 mv s3://bucket/old.txt s3://bucket/new.txt --dryrun
镜像目录aws s3 sync ./dir s3://bucket/dir
预览镜像时删除过期文件aws s3 sync ./dir s3://bucket/dir --delete --dryrun
删除对象aws s3 rm s3://bucket/file.txt
预览删除前缀aws s3 rm s3://bucket/dir/ --recursive --dryrun
创建存储桶aws s3 mb s3://bucket
删除空存储桶aws s3 rb s3://bucket
临时下载链接aws s3 presign s3://bucket/file.txt

常见问题

cp --recursive 和 sync 有什么区别?
cp --recursive 每次运行都复制每个文件。sync 比较两边,只传输新增或变更的文件,对于重复任务更快也更省成本。

我可以在 S3 路径中使用 shell 通配符吗?
不能。AWS CLI 不解释 S3 路径中的 Unix 风格通配符,例如 s3://bucket/*.log。请改用 --recursive 配合 --exclude 和 --include 过滤器。

如何删除存储桶中的所有文件?
对于非版本化存储桶,先用 aws s3 rm s3://bucket --recursive --dryrun 预览,然后去掉 --dryrun 来清空它。aws s3 rb s3://bucket --force 命令可以一步清空并删除非版本化存储桶,但当对象版本或删除标记仍然存在时它会失败。

结论

在 mv、递归 rm 或 sync --delete 之前养成使用 --dryrun 的习惯,然后在脚本和计划任务中复用这些经过审查的命令。