我想知道是否可以检查某个存储桶中是否存在某些文件。
这是我发现的:
Checking if a file is in a S3 bucket using the s3cmd
它应该解决我的问题,但由于某种原因它会一直返回该文件不存在,而它确实存在。此解决方案也有点过时,不使用
doesObjectExist
方法。
Summary of all the methods that can be used in the Amazon S3 web service
这给出了如何使用此方法的语法,但我似乎无法使其工作。
他们是否希望你创建一个布尔变量来保存方法的状态,或该函数是否会直接输出/抛出错误?
这是我目前在bash脚本中使用的代码:
existBool=doesObjectExist(${BucketName}, backup_${DomainName}_${CurrentDate}.zip)
if $existBool ; then
echo 'No worries, the file exists.'
fi
我仅使用文件名来测试它,而不是给出完整路径。但由于我得到的错误是语法错误,我可能只是错误地使用它。
希望有人可以帮助我,告诉我我做错了什么。
!修改
我最终寻找另一种方法来实现这一点,因为使用doesObjectExist
不是最快或最简单的。
答案 0 :(得分:10)
上次我看到性能比较getObjectMetadata
是检查对象是否存在的最快方法。使用可能是head-object
方法的AWS cli,例如:
aws s3api head-object --bucket www.codeengine.com --key index.html
返回:
{
"AcceptRanges": "bytes",
"ContentType": "text/html; charset=utf-8",
"LastModified": "Sun, 08 Jan 2017 22:49:19 GMT",
"ContentLength": 38106,
"ContentEncoding": "gzip",
"ETag": "\"bda80810592763dcaa8627d44c2bf8bb\"",
"StorageClass": "REDUCED_REDUNDANCY",
"CacheControl": "no-cache, no-store",
"Metadata": {}
}
答案 1 :(得分:10)
请注意,即使答案被接受,“aws s3 ls”仍然不能正常工作。它按前缀搜索,而不是按特定对象键搜索。当有人通过在文件名的末尾添加“1”重命名文件时,我发现了这一点,并且存在检查仍将返回True。
(试图将其添加为评论,但还没有足够的代表。)
答案 2 :(得分:7)
一种简单的方法是使用aws s3 ls
exists=$(aws s3 ls $path_to_file)
if [ -z "$exists" ]; then
echo "it does not exist"
else
echo "it exists"
fi
答案 3 :(得分:2)
我通常使用set -eufo pipefail
,以下内容对我来说效果更好,因为我不必担心未设置变量或整个脚本都会退出。
object_exists=$(aws s3api head-object --bucket $bucket --key $key || true)
if [ -z "$object_exists" ]; then
echo "it does not exist"
else
echo "it exists"
fi
答案 4 :(得分:1)
在awscli中,我们执行 ls 和 grep 。
示例:aws s3 ls s3:// <存储桶名称> | grep'文件名'
这可以包含在bash脚本中。
答案 5 :(得分:0)
下面是@DaveMaple和@MichaelGlenn的答案,这是我使用的条件:
aws s3api head-object --bucket <some_bucket> --key <some_key> || not_exist=true
if [ $not_exist ]; then
echo "it does not exist"
else
echo "it exists"
fi
答案 6 :(得分:0)
受上述答案的启发,我还用它来检查文件大小,因为我的存储桶被一些带有 404 个答案的脚本丢弃了。它需要 jq
tho。
minsize=100
s3objhead=$(aws s3api head-object \
--bucket "$BUCKET" --key "$KEY"
--output json || echo '{"ContentLength": 0}')
if [ $(printf "%s" "$s3objhead" | jq '.ContentLength') -lt "$minsize" ]; then
# missing or small
else
# exist and big
fi
答案 7 :(得分:0)
此语句将返回 true
或 false
响应:
aws s3api list-objects-v2 \
--bucket <bucket_name> \
--query "contains(Contents[].Key, '<object_name>')"
因此,如果是问题中提供的示例:
aws s3api list-objects-v2 \
--bucket ${BucketName} \
--query "contains(Contents[].Key, 'backup_${DomainName}_${CurrentDate}.zip')"
我喜欢这种方法,因为:
--query 选项使用 JMESPath 语法进行客户端过滤,并且详细记录了 here 如何使用它。
由于 --query 选项已内置到 aws cli 中,因此无需安装其他依赖项。
您可以先运行不带 --query 选项的命令,例如:
aws s3api list-objects-v2 --bucket <bucket_name>
这将返回一个格式良好的 JSON,例如:
{
"Contents": [
{
"Key": "my_file_1.tar.gz",
"LastModified": "----",
"ETag": "\"-----\"",
"Size": -----,
"StorageClass": "------"
},
{
"Key": "my_file_2.txt",
"LastModified": "----",
"ETag": "\"----\"",
"Size": ----,
"StorageClass": "----"
},
...
]
}
这允许您设计适当的查询。在这种情况下,您要检查 JSON 是否包含列表 Contents
以及该列表中的项目是否具有与您的文件(对象)名称相同的 Key
:
--query "contains(Contents[].Key, '<object_name>')"