aws s3 cp "dist/myfile" "s3://my-bucket/production/myfile"
它总是将myfile
复制到s3 - 我想复制文件,如果它不存在,否则抛出错误。我怎么能这样做?或者至少我如何使用awscli检查文件是否存在?
答案 0 :(得分:28)
您可以通过列出文件来测试文件的存在,并查看它是否返回了某些内容。例如:
aws s3 ls s3://bucket/file.txt | wc -l
如果文件不存在,这将返回零(无行)。
如果您只想复制不存在的文件,请尝试 sync
命令,例如:
aws s3 sync . s3://bucket/ --exclude '*' --include 'file.txt'
这将使本地文件与远程对象同步,只有在它不存在或本地文件与远程对象不同时才复制它。
答案 1 :(得分:10)
因此,事实证明“aws s3 sync”不执行文件,只执行目录。如果你给它一个文件,你会得到......有趣......行为,因为它会像你的目录那样对待任何东西,并在其上抛出一个斜杠。至少aws-cli / 1.6.7 Python / 2.7.5 Darwin / 13.4.0可以。
%% date > test.txt
%% aws s3 sync test.txt s3://bucket/test.txt
warning: Skipping file /Users/draistrick/aws/test.txt/. File does not exist.
所以,如果你真的只想同步一个文件(只有上传,如果存在,如果校验和匹配),你可以这样做:
file="test.txt"
aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
请注意排除/包含顺序 - 如果您反过来,它将不包含任何内容。你的源和包含路径需要在匹配时保持健全,所以也许$(basename $ file)是 - 如果你正在使用完整路径,请包括... aws --debug s3 sync是你的朋友在这里看看包含如何评估。
不要忘记目标是目录密钥,而不是文件密钥。
这是一个有效的例子:
%% file="test.txt"
%% date >> $file
%% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
upload: ./test.txt to s3://bucket/test.txt/test.txt
%% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
%% date >> $file
%% aws s3 sync --exclude '*' --include "$file" "$(dirname $file)" "s3://bucket/"
upload: ./test.txt to s3://bucket/test.txt/test.txt
(现在,如果只有一种方法可以让aws s3 -just-验证校验和,因为它似乎总是做多部分样式校验和..哦,也许一些--dryrun和一些输出抓取和同步.. )
答案 2 :(得分:3)
当且仅当列表成功时,您可以通过列出和复制来执行此操作。
aws s3 ls "s3://my-bucket/production/myfile" || aws s3 cp "dist/myfile" "s3://my-bucket/production/myfile"
修改:替换&&到||如果列表失败,具有所需的效果,请复制
答案 3 :(得分:0)
AWS HACK
如果文件已经存在,您可以运行以下命令来引发错误
wc -c
命令以检查字符数,如果输出为零,则引发错误com = $(aws s3 sync dist / s3:// my-bucket / production / | wc -c); if [[$ com -ne 0 ]];然后退出1;否则退出0; fi;
OR
#!/usr/bin/env bash
com=$(aws s3 sync dist s3://my-bucket/production/ | wc -c)
echo "hello $com"
if [[ $com -ne 0 ]]; then
echo "File already exists"
exit 1
else
echo "success"
exit 0
fi
答案 4 :(得分:0)
我投票赞成阿维吉亚诺。使用上面的示例,我可以在Windows .bat文件中使用它。如果S3路径存在,它将引发错误并结束批处理作业。如果文件不存在,它将继续执行复制功能。希望这可以帮助一些人。
:Step1
aws s3 ls s3://00000000000-fake-bucket/my/s3/path/inbound/test.txt && ECHO Could not copy to S3 bucket becasue S3 Object already exists, ending script. && GOTO :Failure
ECHO No file found in bucket, begin upload.
aws s3 cp Z:\MY\LOCAL\PATH\test.txt s3://00000000000-fake-bucket/my/s3/path/inbound/test.txt --exclude "*" --include "*.txt"
:Step2
ECHO YOU MADE IT, LET'S CELEBRATE
IF %ERRORLEVEL% == 0 GOTO :Success
GOTO :Failure
:Success
echo Job Endedsuccess
GOTO :ExitScript
:Failure
echo BC_Script_Execution_Complete Failure
GOTO :ExitScript
:ExitScript
答案 5 :(得分:0)
您还可以通过aws s3api head-object
子命令检查文件是否存在。与aws s3 ls
相比,它的一个优点是它只需要s3:GetObject
权限而不是s3:ListBucket
。
$ aws s3api head-object --bucket ${BUCKET} --key ${EXISTENT_KEY}
{
"AcceptRanges": "bytes",
"LastModified": "Wed, 1 Jan 2020 00:00:00 GMT",
"ContentLength": 10,
"ETag": "\"...\"",
"VersionId": "...",
"ContentType": "binary/octet-stream",
"ServerSideEncryption": "AES256",
"Metadata": {}
}
$ echo $?
0
$ aws s3api head-object --bucket ${BUCKET} --key ${NON_EXISTENT_KEY}
An error occurred (403) when calling the HeadObject operation: Forbidden
$ echo $?
255
请注意,不存在的对象的HTTP状态代码取决于您是否具有s3:ListObject
权限。有关更多详细信息,请参见API document:
- 如果您对存储桶具有
s3:ListBucket
权限,Amazon S3将返回HTTP状态码404(“无此键”)错误。- 如果您没有
s3:ListBucket
权限,Amazon S3将返回HTTP状态码403(“访问被拒绝”)错误。