如何使用 CLI 删除 AWS S3 中的版本化存储桶?
How do I delete a versioned bucket in AWS S3 using the CLI?
我都试过了s3cmd
:
$ s3cmd -r -f -v del s3://my-versioned-bucket/
以及 AWS CLI:
$ aws s3 rm s3://my-versioned-bucket/ --recursive
但是这两个命令都只是将 DELETE
标记添加到 S3。删除存储桶的命令也不起作用(来自 AWS CLI):
$ aws s3 rb s3://my-versioned-bucket/ --force
Cleaning up. Please wait...
Completed 1 part(s) with ... file(s) remaining
remove_bucket failed: s3://my-versioned-bucket/ A client error (BucketNotEmpty) occurred when calling the DeleteBucket operation: The bucket you tried to delete is not empty. You must delete all versions in the bucket.
好的...怎么样? their documentation for this. S3Cmd says it's a 'fully-featured' S3 command-line tool, but it makes no reference to versions 除了它自己的信息外,没有其他信息。有没有什么方法可以在不使用网络界面的情况下执行此操作,这将花费很长时间并且需要我一直打开笔记本电脑?
一种方法是遍历版本并删除它们。在 CLI 上有点棘手,但正如您提到的 Java,那会更直接:
AmazonS3Client s3 = new AmazonS3Client();
String bucketName = "deleteversions-"+UUID.randomUUID();
//Creates Bucket
s3.createBucket(bucketName);
//Enable Versioning
BucketVersioningConfiguration configuration = new BucketVersioningConfiguration(ENABLED);
s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName, configuration ));
//Puts versions
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("some-bytes".getBytes()), null);
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("other-bytes".getBytes()), null);
//Removes all versions
for ( S3VersionSummary version : S3Versions.inBucket(s3, bucketName) ) {
String key = version.getKey();
String versionId = version.getVersionId();
s3.deleteVersion(bucketName, key, versionId);
}
//Removes the bucket
s3.deleteBucket(bucketName);
System.out.println("Done!");
如果需要,您还可以批量删除调用以提高效率。
您可以删除版本化 s3 存储桶中的所有对象。
但是我不知道如何删除特定的对象。
$ aws s3api delete-objects \
--bucket <value> \
--delete "$(aws s3api list-object-versions \
--bucket <value> | \
jq '{Objects: [.Versions[] | {Key:.Key, VersionId : .VersionId}], Quiet: false}')"
或者没有 jq
:
$ aws s3api delete-objects \
--bucket ${bucket_name} \
--delete "$(aws s3api list-object-versions \
--bucket "${bucket_name}" \
--output=json \
--query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
我运行进入AWS CLI的相同限制。我发现最简单的解决方案是使用 Python 和 boto3:
#!/usr/bin/env python
BUCKET = 'your-bucket-here'
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET)
bucket.object_versions.delete()
# if you want to delete the now-empty bucket as well, uncomment this line:
#bucket.delete()
此答案的先前版本使用 boto,但正如 Chuckles 指出的那样,该解决方案存在大量键的性能问题。
- 删除指定对象,使用 jq 过滤器。
- 您可能需要清理 'DeleteMarkers' 而不仅仅是 'Versions'。
- 使用
$()
而不是 ``
,您可以为存储桶名称和键值嵌入变量。
aws s3api delete-objects --bucket bucket-name --delete "$(aws s3api list-object-versions --bucket bucket-name | jq -M '{Objects: [.["Versions","DeleteMarkers"][]|select(.Key == "key-value")| {Key:.Key, VersionId : .VersionId}], Quiet: false}')"
这是一个单一的衬垫,您可以将其剪切并粘贴到命令行中以删除所有版本并删除标记(它需要 aws 工具,将 yourbucket-name-backup 替换为您的存储桶名称)
echo '#!/bin/bash' > deleteBucketScript.sh \
&& aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^VERSIONS" |\
awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "" --version-id "";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh; echo '#!/bin/bash' > \
deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^DELETEMARKERS" | grep -v "null" \
| awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "" --version-id "";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh;
那么你可以使用:
aws s3 rb s3://bucket-name --force
我 运行 遇到了 的问题,因为 list_buckets
生成器用于创建一个名为 all_keys
的庞大列表,我花了一个小时没有完成。这个调整似乎对我更有效,我的存储桶中有将近一百万个对象并且还在增加!
import boto
s3 = boto.connect_s3()
bucket = s3.get_bucket("your-bucket-name-here")
chunk_counter = 0 #this is simply a nice to have
keys = []
for key in bucket.list_versions():
keys.append(key)
if len(keys) > 1000:
bucket.delete_keys(keys)
chunk_counter += 1
keys = []
print("Another 1000 done.... {n} chunks so far".format(n=chunk_counter))
#bucket.delete() #as per usual uncomment if you're sure!
希望这对遇到这个 S3 噩梦的其他人有所帮助!
使用 boto3
比建议的 boto
解决方案更容易删除 S3 存储桶中的所有对象版本:
#!/usr/bin/env python
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('your-bucket-name')
bucket.object_versions.all().delete()
对于非常大量的对象版本也能正常工作,尽管在那种情况下可能需要一些时间。
我发现其他答案要么不完整,要么需要安装外部依赖项(如 boto),因此这里是受这些启发但更深入的答案。
如 Working with Delete Markers 中所述,在删除版本化存储桶之前,必须完全删除其所有版本,这是一个两步过程:
- "delete" 存储桶中的所有版本对象,将它们标记为
已删除但实际上并未删除它们
- 删除所有删除标记对象完成删除
这是对我有用的纯 CLI 解决方案(受其他答案启发):
#!/usr/bin/env bash
bucket_name=...
del_s3_bucket_obj()
{
local bucket_name=
local obj_type=
local query="{Objects: $obj_type[].{Key:Key,VersionId:VersionId}}"
local s3_objects=$(aws s3api list-object-versions --bucket ${bucket_name} --output=json --query="$query")
if ! (echo $s3_objects | grep -q '"Objects": null'); then
aws s3api delete-objects --bucket "${bucket_name}" --delete "$s3_objects"
fi
}
del_s3_bucket_obj ${bucket_name} 'Versions'
del_s3_bucket_obj ${bucket_name} 'DeleteMarkers'
完成后,以下将起作用:
aws s3 rb "s3://${bucket_name}"
虽然不确定 1000 多个对象的情况如何,但如果有人可以报告那就太棒了。
到目前为止,我发现的最简单的方法是使用此 CLI 工具 s3wipe
。它作为 docker 容器提供,因此您可以像这样使用它:
$ docker run -it --rm slmingol/s3wipe --help
usage: s3wipe [-h] --path PATH [--id ID] [--key KEY] [--dryrun] [--quiet]
[--batchsize BATCHSIZE] [--maxqueue MAXQUEUE]
[--maxthreads MAXTHREADS] [--delbucket] [--region REGION]
Recursively delete all keys in an S3 path
optional arguments:
-h, --help show this help message and exit
--path PATH S3 path to delete (e.g. s3://bucket/path)
--id ID Your AWS access key ID
--key KEY Your AWS secret access key
--dryrun Don't delete. Print what we would have deleted
--quiet Suprress all non-error output
--batchsize BATCHSIZE # of keys to batch delete (default 100)
--maxqueue MAXQUEUE Max size of deletion queue (default 10k)
--maxthreads MAXTHREADS Max number of threads (default 100)
--delbucket If S3 path is a bucket path, delete the bucket also
--region REGION Region of target S3 bucket. Default vaue `us-
east-1`
例子
这是一个示例,其中我删除了存储桶中的所有版本化对象,然后删除了该存储桶:
$ docker run -it --rm slmingol/s3wipe \
--id $(aws configure get default.aws_access_key_id) \
--key $(aws configure get default.aws_secret_access_key) \
--path s3://bw-tf-backends-aws-example-logs \
--delbucket
[2019-02-20@03:39:16] INFO: Deleting from bucket: bw-tf-backends-aws-example-logs, path: None
[2019-02-20@03:39:16] INFO: Getting subdirs to feed to list threads
[2019-02-20@03:39:18] INFO: Done deleting keys
[2019-02-20@03:39:18] INFO: Bucket is empty. Attempting to remove bucket
工作原理
这里有一点要解包,但上面的内容是:
docker run -it --rm mikelorant/s3wipe
- 以交互方式运行 s3wipe
容器并在每次执行后将其删除
--id
& --key
- 在 中传递我们的访问密钥和访问 ID
aws configure get default.aws_access_key_id
- 检索我们的密钥 id
aws configure get default.aws_secret_access_key
- 检索我们的密钥
--path s3://bw-tf-backends-aws-example-logs
- 我们要删除的存储桶
--delbucket
- 清空后删除桶
参考资料
https://gist.github.com/wknapik/191619bfa650b8572115cd07197f3baf
#!/usr/bin/env bash
set -eEo pipefail
shopt -s inherit_errexit >/dev/null 2>&1 || true
if [[ ! "$#" -eq 2 || "" != --bucket ]]; then
echo -e "USAGE: $(basename "[=10=]") --bucket <bucket>"
exit 2
fi
# $@ := bucket_name
empty_bucket() {
local -r bucket="${1:?}"
for object_type in Versions DeleteMarkers; do
local opt=() next_token=""
while [[ "$next_token" != null ]]; do
page="$(aws s3api list-object-versions --bucket "$bucket" --output json --max-items 1000 "${opt[@]}" \
--query="[{Objects: ${object_type}[].{Key:Key, VersionId:VersionId}}, NextToken]")"
objects="$(jq -r '.[0]' <<<"$page")"
next_token="$(jq -r '.[1]' <<<"$page")"
case "$(jq -r .Objects <<<"$objects")" in
'[]'|null) break;;
*) opt=(--starting-token "$next_token")
aws s3api delete-objects --bucket "$bucket" --delete "$objects";;
esac
done
done
}
empty_bucket "${2#s3://}"
例如empty_bucket.sh --bucket foo
这将删除所有对象版本,并以 1000 个为一批删除存储桶中的标记。之后,可以使用 aws s3 rb s3://foo
删除存储桶。
需要 bash、awscli 和 jq。
在此处找到此 bash 脚本:https://gist.github.com/weavenet/f40b09847ac17dd99d16
对我来说工作正常。
我将脚本保存为:delete_all_versions.sh 然后简单地 运行:
./delete_all_versions.sh my_foobar_bucket
这毫无瑕疵。
不需要 python 或 boto 或任何东西。
这对我有用。也许 运行 某些东西的更高版本及以上 > 1000 项。 运行 现在有几百万个文件。然而,半天后仍未完成,无法在 AWS GUI 中验证 =/
# Set bucket name to clearout
BUCKET = 'bucket-to-clear'
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET)
max_len = 1000 # max 1000 items at one req
chunk_counter = 0 # just to keep track
keys = [] # collect to delete
# clear files
def clearout():
global bucket
global chunk_counter
global keys
result = bucket.delete_objects(Delete=dict(Objects=keys))
if result["ResponseMetadata"]["HTTPStatusCode"] != 200:
print("Issue with response")
print(result)
chunk_counter += 1
keys = []
print(". {n} chunks so far".format(n=chunk_counter))
return
# start
for key in bucket.object_versions.all():
item = {'Key': key.object_key, 'VersionId': key.id}
keys.append(item)
if len(keys) >= max_len:
clearout()
# make sure last files are cleared as well
if len(keys) > 0:
clearout()
print("")
print("Done, {n} items deleted".format(n=chunk_counter*max_len))
#bucket.delete() #as per usual uncomment if you're sure!
对于通过 ~/.aws/config
使用多个配置文件的用户
import boto3
PROFILE = "my_profile"
BUCKET = "my_bucket"
session = boto3.Session(profile_name = PROFILE)
s3 = session.resource('s3')
bucket = s3.Bucket(BUCKET)
bucket.object_versions.delete()
您可以使用生命周期规则从 AWS 控制台执行此操作。
打开有问题的桶。单击顶部的“管理”选项卡。
确保选择了生命周期子选项卡。
单击 + 添加生命周期规则
在第 1 步(名称和范围)中输入规则名称(例如 removeall)
单击步骤 2(转换)旁边的下一步
保持原样并单击“下一步”。
您现在处于 3. 过期步骤。
选中当前版本和以前版本的复选框。
单击 "Expire current version of object" 的复选框并为“对象创建后 _____ 天后”输入数字 1
单击 "Permanently delete previous versions" 的复选框并输入数字 1
"After _____ days from becoming a previous version"
单击 "Clean up incomplete multipart uploads" 的复选框
并为 "After ____ days from start of upload" 输入数字 1
点击下一步
回顾一下你刚刚做了什么。
单击保存
过一天回来看看效果如何。
这两 bash 行足以让我启用存储桶删除!
1: 删除对象
aws s3api delete-objects --bucket ${buckettoempty} --delete "$(aws s3api list-object-versions --bucket ${buckettoempty} --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
2:删除标记
aws s3api delete-objects --bucket ${buckettoempty} --delete "$(aws s3api list-object-versions --bucket ${buckettoempty} --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')"
要添加此处提供的 python 解决方案:如果您遇到 boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request
错误,请尝试使用以下数据创建 ~/.boto 文件:
[Credentials]
aws_access_key_id = aws_access_key_id
aws_secret_access_key = aws_secret_access_key
[s3]
host=s3.eu-central-1.amazonaws.com
aws_access_key_id = aws_access_key_id
aws_secret_access_key = aws_secret_access_key
帮我删除了法兰克福地区的bucket。
原回答:
尽管从技术上讲它不是 AWS CLI,但我还是建议使用 AWS Tools for Powershell 来完成此任务。然后你可以使用如下简单的命令:
Remove-S3Bucket -BucketName {bucket-name} -DeleteBucketContent -Force -Region {region}
如文档中所述,DeleteBucketContent 标志执行以下操作:
"If set, all remaining objects and/or object versions in the bucket
are deleted proir (sic) to the bucket itself being deleted"
如果您必须 delete/empty 大型 S3 存储桶,删除每个对象和版本会变得非常低效(而且代价高昂)。让 AWS 使所有对象和版本过期通常更方便。
aws s3api put-bucket-lifecycle-configuration \
--lifecycle-configuration '{"Rules":[{
"ID":"empty-bucket",
"Status":"Enabled",
"Prefix":"",
"Expiration":{"Days":1},
"NoncurrentVersionExpiration":{"NoncurrentDays":1}
}]}' \
--bucket YOUR-BUCKET
然后您只需要等待 1 天 即可删除存储桶:
aws s3api delete-bucket --bucket YOUR-BUCKET
如果您想要纯 CLI 方法(使用 jq):
aws s3api list-object-versions \
--bucket $bucket \
--region $region \
--query "Versions[].Key" \
--output json | jq 'unique' | jq -r '.[]' | while read key; do
echo "deleting versions of $key"
aws s3api list-object-versions \
--bucket $bucket \
--region $region \
--prefix $key \
--query "Versions[].VersionId" \
--output json | jq 'unique' | jq -r '.[]' | while read version; do
echo "deleting $version"
aws s3api delete-object \
--bucket $bucket \
--key $key \
--version-id $version \
--region $region
done
done
目前看来,AWS S3 控制台中有一个 Empty
按钮。
只需 select 您的存储桶并单击它。它会要求您输入 permanently delete
来确认您的决定
请注意,这不会删除存储桶本身。
您可以使用aws-cli删除s3 bucket
aws s3 rb s3://your-bucket-name
如果 aws cli 未安装在您的计算机中,您可以使用以下命令:
对于 Linux 或 ubuntu:
sudo apt-get install aws-cli
然后通过以下方式检查是否已安装:
aws --version
现在通过提供 aws-access-credentials 进行配置
aws configure
然后提供访问密钥和秘密访问密钥以及您所在的地区
我为 N 个存储桶找到并实施的简单 bash 循环:
for b in $(ListOfBuckets); do \
echo "Emptying $b"; \
aws s3api delete-objects --bucket $b --delete "$(aws s3api list-object-versions --bucket $b --output=json --query='{Objects: *[].{Key:Key,VersionId:VersionId}}')"; \
done
我用 Python3 和 argv 改进了 。
- 将以下脚本另存为
s3_rm.py
.
#!/usr/bin/env python3
import sys
import boto3
def main():
args = sys.argv[1:]
if (len(args) < 1):
print("Usage: {} s3_bucket_name".format(sys.argv[0]))
exit()
s3 = boto3.resource('s3')
bucket = s3.Bucket(args[0])
bucket.object_versions.delete()
# if you want to delete the now-empty bucket as well, uncomment this line:
#bucket.delete()
if __name__ == "__main__":
main()
- 添加
chmod +x s3_rm.py
.
- 运行 类似
./s3_rm.py my_bucket_name
. 的函数
我都试过了s3cmd
:
$ s3cmd -r -f -v del s3://my-versioned-bucket/
以及 AWS CLI:
$ aws s3 rm s3://my-versioned-bucket/ --recursive
但是这两个命令都只是将 DELETE
标记添加到 S3。删除存储桶的命令也不起作用(来自 AWS CLI):
$ aws s3 rb s3://my-versioned-bucket/ --force
Cleaning up. Please wait...
Completed 1 part(s) with ... file(s) remaining
remove_bucket failed: s3://my-versioned-bucket/ A client error (BucketNotEmpty) occurred when calling the DeleteBucket operation: The bucket you tried to delete is not empty. You must delete all versions in the bucket.
好的...怎么样? their documentation for this. S3Cmd says it's a 'fully-featured' S3 command-line tool, but it makes no reference to versions 除了它自己的信息外,没有其他信息。有没有什么方法可以在不使用网络界面的情况下执行此操作,这将花费很长时间并且需要我一直打开笔记本电脑?
一种方法是遍历版本并删除它们。在 CLI 上有点棘手,但正如您提到的 Java,那会更直接:
AmazonS3Client s3 = new AmazonS3Client();
String bucketName = "deleteversions-"+UUID.randomUUID();
//Creates Bucket
s3.createBucket(bucketName);
//Enable Versioning
BucketVersioningConfiguration configuration = new BucketVersioningConfiguration(ENABLED);
s3.setBucketVersioningConfiguration(new SetBucketVersioningConfigurationRequest(bucketName, configuration ));
//Puts versions
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("some-bytes".getBytes()), null);
s3.putObject(bucketName, "some-key",new ByteArrayInputStream("other-bytes".getBytes()), null);
//Removes all versions
for ( S3VersionSummary version : S3Versions.inBucket(s3, bucketName) ) {
String key = version.getKey();
String versionId = version.getVersionId();
s3.deleteVersion(bucketName, key, versionId);
}
//Removes the bucket
s3.deleteBucket(bucketName);
System.out.println("Done!");
如果需要,您还可以批量删除调用以提高效率。
您可以删除版本化 s3 存储桶中的所有对象。 但是我不知道如何删除特定的对象。
$ aws s3api delete-objects \
--bucket <value> \
--delete "$(aws s3api list-object-versions \
--bucket <value> | \
jq '{Objects: [.Versions[] | {Key:.Key, VersionId : .VersionId}], Quiet: false}')"
或者没有 jq
:
$ aws s3api delete-objects \
--bucket ${bucket_name} \
--delete "$(aws s3api list-object-versions \
--bucket "${bucket_name}" \
--output=json \
--query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
我运行进入AWS CLI的相同限制。我发现最简单的解决方案是使用 Python 和 boto3:
#!/usr/bin/env python
BUCKET = 'your-bucket-here'
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET)
bucket.object_versions.delete()
# if you want to delete the now-empty bucket as well, uncomment this line:
#bucket.delete()
此答案的先前版本使用 boto,但正如 Chuckles 指出的那样,该解决方案存在大量键的性能问题。
- 删除指定对象,使用 jq 过滤器。
- 您可能需要清理 'DeleteMarkers' 而不仅仅是 'Versions'。
- 使用
$()
而不是``
,您可以为存储桶名称和键值嵌入变量。
aws s3api delete-objects --bucket bucket-name --delete "$(aws s3api list-object-versions --bucket bucket-name | jq -M '{Objects: [.["Versions","DeleteMarkers"][]|select(.Key == "key-value")| {Key:.Key, VersionId : .VersionId}], Quiet: false}')"
这是一个单一的衬垫,您可以将其剪切并粘贴到命令行中以删除所有版本并删除标记(它需要 aws 工具,将 yourbucket-name-backup 替换为您的存储桶名称)
echo '#!/bin/bash' > deleteBucketScript.sh \
&& aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^VERSIONS" |\
awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "" --version-id "";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh; echo '#!/bin/bash' > \
deleteBucketScript.sh && aws --output text s3api list-object-versions --bucket $BUCKET_TO_PERGE \
| grep -E "^DELETEMARKERS" | grep -v "null" \
| awk '{print "aws s3api delete-object --bucket $BUCKET_TO_PERGE --key "" --version-id "";"}' >> \
deleteBucketScript.sh && . deleteBucketScript.sh; rm -f deleteBucketScript.sh;
那么你可以使用:
aws s3 rb s3://bucket-name --force
我 运行 遇到了 list_buckets
生成器用于创建一个名为 all_keys
的庞大列表,我花了一个小时没有完成。这个调整似乎对我更有效,我的存储桶中有将近一百万个对象并且还在增加!
import boto
s3 = boto.connect_s3()
bucket = s3.get_bucket("your-bucket-name-here")
chunk_counter = 0 #this is simply a nice to have
keys = []
for key in bucket.list_versions():
keys.append(key)
if len(keys) > 1000:
bucket.delete_keys(keys)
chunk_counter += 1
keys = []
print("Another 1000 done.... {n} chunks so far".format(n=chunk_counter))
#bucket.delete() #as per usual uncomment if you're sure!
希望这对遇到这个 S3 噩梦的其他人有所帮助!
使用 boto3
比建议的 boto
解决方案更容易删除 S3 存储桶中的所有对象版本:
#!/usr/bin/env python
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket('your-bucket-name')
bucket.object_versions.all().delete()
对于非常大量的对象版本也能正常工作,尽管在那种情况下可能需要一些时间。
我发现其他答案要么不完整,要么需要安装外部依赖项(如 boto),因此这里是受这些启发但更深入的答案。
如 Working with Delete Markers 中所述,在删除版本化存储桶之前,必须完全删除其所有版本,这是一个两步过程:
- "delete" 存储桶中的所有版本对象,将它们标记为 已删除但实际上并未删除它们
- 删除所有删除标记对象完成删除
这是对我有用的纯 CLI 解决方案(受其他答案启发):
#!/usr/bin/env bash
bucket_name=...
del_s3_bucket_obj()
{
local bucket_name=
local obj_type=
local query="{Objects: $obj_type[].{Key:Key,VersionId:VersionId}}"
local s3_objects=$(aws s3api list-object-versions --bucket ${bucket_name} --output=json --query="$query")
if ! (echo $s3_objects | grep -q '"Objects": null'); then
aws s3api delete-objects --bucket "${bucket_name}" --delete "$s3_objects"
fi
}
del_s3_bucket_obj ${bucket_name} 'Versions'
del_s3_bucket_obj ${bucket_name} 'DeleteMarkers'
完成后,以下将起作用:
aws s3 rb "s3://${bucket_name}"
虽然不确定 1000 多个对象的情况如何,但如果有人可以报告那就太棒了。
到目前为止,我发现的最简单的方法是使用此 CLI 工具 s3wipe
。它作为 docker 容器提供,因此您可以像这样使用它:
$ docker run -it --rm slmingol/s3wipe --help
usage: s3wipe [-h] --path PATH [--id ID] [--key KEY] [--dryrun] [--quiet]
[--batchsize BATCHSIZE] [--maxqueue MAXQUEUE]
[--maxthreads MAXTHREADS] [--delbucket] [--region REGION]
Recursively delete all keys in an S3 path
optional arguments:
-h, --help show this help message and exit
--path PATH S3 path to delete (e.g. s3://bucket/path)
--id ID Your AWS access key ID
--key KEY Your AWS secret access key
--dryrun Don't delete. Print what we would have deleted
--quiet Suprress all non-error output
--batchsize BATCHSIZE # of keys to batch delete (default 100)
--maxqueue MAXQUEUE Max size of deletion queue (default 10k)
--maxthreads MAXTHREADS Max number of threads (default 100)
--delbucket If S3 path is a bucket path, delete the bucket also
--region REGION Region of target S3 bucket. Default vaue `us-
east-1`
例子
这是一个示例,其中我删除了存储桶中的所有版本化对象,然后删除了该存储桶:
$ docker run -it --rm slmingol/s3wipe \
--id $(aws configure get default.aws_access_key_id) \
--key $(aws configure get default.aws_secret_access_key) \
--path s3://bw-tf-backends-aws-example-logs \
--delbucket
[2019-02-20@03:39:16] INFO: Deleting from bucket: bw-tf-backends-aws-example-logs, path: None
[2019-02-20@03:39:16] INFO: Getting subdirs to feed to list threads
[2019-02-20@03:39:18] INFO: Done deleting keys
[2019-02-20@03:39:18] INFO: Bucket is empty. Attempting to remove bucket
工作原理
这里有一点要解包,但上面的内容是:
docker run -it --rm mikelorant/s3wipe
- 以交互方式运行s3wipe
容器并在每次执行后将其删除--id
&--key
- 在 中传递我们的访问密钥和访问 ID
aws configure get default.aws_access_key_id
- 检索我们的密钥 idaws configure get default.aws_secret_access_key
- 检索我们的密钥--path s3://bw-tf-backends-aws-example-logs
- 我们要删除的存储桶--delbucket
- 清空后删除桶
参考资料
https://gist.github.com/wknapik/191619bfa650b8572115cd07197f3baf
#!/usr/bin/env bash
set -eEo pipefail
shopt -s inherit_errexit >/dev/null 2>&1 || true
if [[ ! "$#" -eq 2 || "" != --bucket ]]; then
echo -e "USAGE: $(basename "[=10=]") --bucket <bucket>"
exit 2
fi
# $@ := bucket_name
empty_bucket() {
local -r bucket="${1:?}"
for object_type in Versions DeleteMarkers; do
local opt=() next_token=""
while [[ "$next_token" != null ]]; do
page="$(aws s3api list-object-versions --bucket "$bucket" --output json --max-items 1000 "${opt[@]}" \
--query="[{Objects: ${object_type}[].{Key:Key, VersionId:VersionId}}, NextToken]")"
objects="$(jq -r '.[0]' <<<"$page")"
next_token="$(jq -r '.[1]' <<<"$page")"
case "$(jq -r .Objects <<<"$objects")" in
'[]'|null) break;;
*) opt=(--starting-token "$next_token")
aws s3api delete-objects --bucket "$bucket" --delete "$objects";;
esac
done
done
}
empty_bucket "${2#s3://}"
例如empty_bucket.sh --bucket foo
这将删除所有对象版本,并以 1000 个为一批删除存储桶中的标记。之后,可以使用 aws s3 rb s3://foo
删除存储桶。
需要 bash、awscli 和 jq。
在此处找到此 bash 脚本:https://gist.github.com/weavenet/f40b09847ac17dd99d16
对我来说工作正常。
我将脚本保存为:delete_all_versions.sh 然后简单地 运行:
./delete_all_versions.sh my_foobar_bucket
这毫无瑕疵。
不需要 python 或 boto 或任何东西。
这对我有用。也许 运行 某些东西的更高版本及以上 > 1000 项。 运行 现在有几百万个文件。然而,半天后仍未完成,无法在 AWS GUI 中验证 =/
# Set bucket name to clearout
BUCKET = 'bucket-to-clear'
import boto3
s3 = boto3.resource('s3')
bucket = s3.Bucket(BUCKET)
max_len = 1000 # max 1000 items at one req
chunk_counter = 0 # just to keep track
keys = [] # collect to delete
# clear files
def clearout():
global bucket
global chunk_counter
global keys
result = bucket.delete_objects(Delete=dict(Objects=keys))
if result["ResponseMetadata"]["HTTPStatusCode"] != 200:
print("Issue with response")
print(result)
chunk_counter += 1
keys = []
print(". {n} chunks so far".format(n=chunk_counter))
return
# start
for key in bucket.object_versions.all():
item = {'Key': key.object_key, 'VersionId': key.id}
keys.append(item)
if len(keys) >= max_len:
clearout()
# make sure last files are cleared as well
if len(keys) > 0:
clearout()
print("")
print("Done, {n} items deleted".format(n=chunk_counter*max_len))
#bucket.delete() #as per usual uncomment if you're sure!
对于通过 ~/.aws/config
import boto3
PROFILE = "my_profile"
BUCKET = "my_bucket"
session = boto3.Session(profile_name = PROFILE)
s3 = session.resource('s3')
bucket = s3.Bucket(BUCKET)
bucket.object_versions.delete()
您可以使用生命周期规则从 AWS 控制台执行此操作。
打开有问题的桶。单击顶部的“管理”选项卡。 确保选择了生命周期子选项卡。 单击 + 添加生命周期规则
在第 1 步(名称和范围)中输入规则名称(例如 removeall) 单击步骤 2(转换)旁边的下一步 保持原样并单击“下一步”。
您现在处于 3. 过期步骤。 选中当前版本和以前版本的复选框。 单击 "Expire current version of object" 的复选框并为“对象创建后 _____ 天后”输入数字 1 单击 "Permanently delete previous versions" 的复选框并输入数字 1 "After _____ days from becoming a previous version"
单击 "Clean up incomplete multipart uploads" 的复选框
并为 "After ____ days from start of upload" 输入数字 1
点击下一步
回顾一下你刚刚做了什么。
单击保存
过一天回来看看效果如何。
这两 bash 行足以让我启用存储桶删除!
1: 删除对象
aws s3api delete-objects --bucket ${buckettoempty} --delete "$(aws s3api list-object-versions --bucket ${buckettoempty} --query='{Objects: Versions[].{Key:Key,VersionId:VersionId}}')"
2:删除标记
aws s3api delete-objects --bucket ${buckettoempty} --delete "$(aws s3api list-object-versions --bucket ${buckettoempty} --query='{Objects: DeleteMarkers[].{Key:Key,VersionId:VersionId}}')"
要添加此处提供的 python 解决方案:如果您遇到 boto.exception.S3ResponseError: S3ResponseError: 400 Bad Request
错误,请尝试使用以下数据创建 ~/.boto 文件:
[Credentials]
aws_access_key_id = aws_access_key_id
aws_secret_access_key = aws_secret_access_key
[s3]
host=s3.eu-central-1.amazonaws.com
aws_access_key_id = aws_access_key_id
aws_secret_access_key = aws_secret_access_key
帮我删除了法兰克福地区的bucket。
原回答:
尽管从技术上讲它不是 AWS CLI,但我还是建议使用 AWS Tools for Powershell 来完成此任务。然后你可以使用如下简单的命令:
Remove-S3Bucket -BucketName {bucket-name} -DeleteBucketContent -Force -Region {region}
如文档中所述,DeleteBucketContent 标志执行以下操作:
"If set, all remaining objects and/or object versions in the bucket are deleted proir (sic) to the bucket itself being deleted"
如果您必须 delete/empty 大型 S3 存储桶,删除每个对象和版本会变得非常低效(而且代价高昂)。让 AWS 使所有对象和版本过期通常更方便。
aws s3api put-bucket-lifecycle-configuration \
--lifecycle-configuration '{"Rules":[{
"ID":"empty-bucket",
"Status":"Enabled",
"Prefix":"",
"Expiration":{"Days":1},
"NoncurrentVersionExpiration":{"NoncurrentDays":1}
}]}' \
--bucket YOUR-BUCKET
然后您只需要等待 1 天 即可删除存储桶:
aws s3api delete-bucket --bucket YOUR-BUCKET
如果您想要纯 CLI 方法(使用 jq):
aws s3api list-object-versions \
--bucket $bucket \
--region $region \
--query "Versions[].Key" \
--output json | jq 'unique' | jq -r '.[]' | while read key; do
echo "deleting versions of $key"
aws s3api list-object-versions \
--bucket $bucket \
--region $region \
--prefix $key \
--query "Versions[].VersionId" \
--output json | jq 'unique' | jq -r '.[]' | while read version; do
echo "deleting $version"
aws s3api delete-object \
--bucket $bucket \
--key $key \
--version-id $version \
--region $region
done
done
目前看来,AWS S3 控制台中有一个 Empty
按钮。
只需 select 您的存储桶并单击它。它会要求您输入 permanently delete
来确认您的决定
请注意,这不会删除存储桶本身。
您可以使用aws-cli删除s3 bucket
aws s3 rb s3://your-bucket-name
如果 aws cli 未安装在您的计算机中,您可以使用以下命令: 对于 Linux 或 ubuntu:
sudo apt-get install aws-cli
然后通过以下方式检查是否已安装:
aws --version
现在通过提供 aws-access-credentials 进行配置
aws configure
然后提供访问密钥和秘密访问密钥以及您所在的地区
我为 N 个存储桶找到并实施的简单 bash 循环:
for b in $(ListOfBuckets); do \
echo "Emptying $b"; \
aws s3api delete-objects --bucket $b --delete "$(aws s3api list-object-versions --bucket $b --output=json --query='{Objects: *[].{Key:Key,VersionId:VersionId}}')"; \
done
我用 Python3 和 argv 改进了
- 将以下脚本另存为
s3_rm.py
.
#!/usr/bin/env python3
import sys
import boto3
def main():
args = sys.argv[1:]
if (len(args) < 1):
print("Usage: {} s3_bucket_name".format(sys.argv[0]))
exit()
s3 = boto3.resource('s3')
bucket = s3.Bucket(args[0])
bucket.object_versions.delete()
# if you want to delete the now-empty bucket as well, uncomment this line:
#bucket.delete()
if __name__ == "__main__":
main()
- 添加
chmod +x s3_rm.py
. - 运行 类似
./s3_rm.py my_bucket_name
. 的函数