问题
I work exclusively in a Mac OSX environment and I am trying to automate uploading .zip files onto my amazon s3 bucket.
I have been trying the last couple of days and I am really stumped. I have tried many different variations of what I will post and I always get the same result of errors. I even tried having my AppleScript call a .sh file and still could not get a result.
I am not going to post my whole code just the part where I am doing the cURL command. My string that contains my entire cURL command is all in one line because I read that was best for AppleScript to understand.
set objectName to "My\\ Big\\ Test.zip"
set dateFormatted to do shell script "date -R"
set s3Bucket to "zipsOnAmazon"
set fileName to zipFile
set relativePath to (" " & s3Bucket & "/" & objectName & " ")
set s3AccessKey to "my-key"
set s3SecretKey to "my-secret"
set contentType to "application/octet-stream"
set stringToSign to "PUT " & contentType & " " & dateFormatted & relativePath & " "
set signature to "echo -en " & stringToSign & " | openssl sha1 -hmac " & s3SecretKey & " - binary | base64"
set theBigCommand to "-X PUT -T " & fileName & " \\ -H \"Host: " & s3Bucket & ".s3-us-west-2.amazonaws.com \\ -H \"Date: " & dateFormatted & " \\ -H \"Content-Type: " & contentType & " \\ -H \"Authorization: AWS " & s3AccessKey & ":" & signature & " \\ https://" & s3Bucket & ".s3-us-west-2.amazonaws.com/" & objectName & ""
display dialog ("curl " & theBigCommand & "")
do shell script ("curl " & theBigCommand & "")
So I end up getting two major error messages:
curl: option -0800: is unknown: unknown option '-'
"Unable to open 'https://zipsOnAmazon.s3-us-west-2.amazonaws.com/My Big Test.zip': No such file or directory"
This error confuses me because I am not trying to open that file I am trying to add it to that path with that name. But every single cURL example I see has the bucket and the objectName there.
If anyone could point me in the right direction that would be greatly appreciated. Thanks in advance.
回答1:
Your code had a bunch of syntactical errors in it, which was why the shell command was throwing errors. Most weren't really much more than typos, undoubtedly because you chose to write out your command string in one long line, and couldn't keep track of where your opening and closing quotes were falling. But there were one or two bigger anomalies.
My string that contains my entire cURL command is all in one line because I read that was best for AppleScript to understand.
Nope.
AppleScript doesn't care one way or the other. It's certainly more difficult for a human to understand, but what I did was to send the command string to the clipboard in AppleScript (this parses the escaped characters), and then paste it into Terminal to see what's what.
I'll paste the new modified code and try and walk you through the changes:
set objectName to "My Big Test.zip"
I removed your manual escaping of the spaces, because AppleScript has a means by which it can escape strings and it does this very well, esuring the resulting form will be interpreted corrected by a shell command.
set dateFormatted to do shell script "date -R"
set s3Bucket to "zipsOnAmazon"
set fileName to zipFile
set relativePath to (" " & s3Bucket & "/" & objectName & " ")
set s3AccessKey to "my-key"
set s3SecretKey to "my-secret"
set contentType to "application/octet-stream"
set stringToSign to "PUT " & contentType & " " & dateFormatted & relativePath & " "
I removed the end components of your command string and used them to create a variable that contains the URL for curl
. Within this concatenation is the now-unescaped objectName
. Instead, we'll get AppleScript to treat the entire URL for us, rather than just one individual component.
set OPTURL to "https://" & s3Bucket & ".s3-us-west-2.amazonaws.com/" & objectName
This was one of the big errors. You incorporated what is now the signatureCommand
string into your curl
command string. It is possible to do this, but a) you did it wrongly; and b) there's no point making it more difficult for yourself than is necessary.
The echo
command through to the openssl
and base64
commands are best handled first, in order to obtain the signature.
This is also where your first error was thrown (curl: option -0800: is unknown: unknown option '-'
): it was simple typo, where you wrote - binary
instead of -binary
,
set signatureCommand to "echo -en " & stringToSign & ¬
" | openssl sha1 -hmac " & s3SecretKey & " -binary | base64"
set signature to do shell script signatureCommand
The signature
variable is now, itself, the result of a shell command. But it's now the correct result.
Next, I've formatted the string over multiple lines to make it more human-readable. AppleScript is very content with this. I removed all the myriad backslashes you had all over the place—they were redundant. I also exchanged your backslashed-double quotes for single quotes. Either are acceptable, but the latter made it much more readable without confusing where double-quotes were starting and ending.
After I lined up the headers, it was clear that losing track of double-quotes was the issue: your headers would have an opening quotation mark, but not have a closing one. Therefore, the next opening mark was taken to be the previous closing mark, which upset all the text strings inside the curl
command.
Here's the correctly-formatted declaration:
set theBigCommand to "-X PUT -T " & quoted form of fileName & ¬
" -H 'Host: " & s3Bucket & ".s3-us-west-2.amazonaws.com'" & ¬
" -H 'Date: " & dateFormatted & "'" & ¬
" -H 'Content-Type: " & contentType & "'" & ¬
" -H 'Authorization: AWS " & s3AccessKey & ":" & signature & "'" & ¬
" --url " & quoted form of OPTURL
Note the use of a proprety called the quoted form of
a string. This is the way AppleScript escapes strings for using them inside shell commands. Most of the time, it's a simple case of letting AppleScript surround a string in single quotes, which is all that was required for the URL. I also applied this formatting to the fileName
variable, which can now have spaces in its names without bother.
display dialog ("curl " & theBigCommand & "")
do shell script ("curl " & theBigCommand & "")
I ran the curl
command and received this output:
<?xml version="1.0" encoding="UTF-8"?><Error><Code>HttpVersionNotSupported</Code><Message>The HTTP version specified is not supported.</Message><RequestId>C413DB82E1D5502B</RequestId><HostId>p4nc6t/hwGE5l29+y3wR/VUgStZqtjMi9tem/0yl3zSCx1FyeJ/8FZW7ZFEZPYVPxkMF9wm54IxOaPGeVcprpGBrc1suEZKU</HostId></Error>
which is partly expected, given I was using duff placeholders for real filenames and access tokens. I'm not sure how to interpret the message regarding the HTTP version not being supported. I suggest you use your actual data to give the code a try and see what the server returns back to you. But this, at least, confirms that the curl
command is now working appropriately.
If you do end up getting stuck on the server side of things, I came across this PHP script that appears to accomplish the same task as you're attempting to do. I don't know whether or not you're familiar with PHP; you don't really need to be, as it's quite straightforward to read and interpret what's happening.
If your script fails, you could try mimicking the steps in that PHP script and creating the appropriate AppleScript commands to the same effect.
来源:https://stackoverflow.com/questions/48573045/applescript-do-shell-script-curl-command-for-amazon-s3