0

I am trying to run a aws command to update the cache control metadata for one file:

aws s3 cp s3://mybucket/file.js s3://mybucket/file.js --region us-east-1 --acl public-read --metadata-directive REPLACE --cache-control "public, max-age=86400"

However, I want to run this command against multiple selected files. So I went ahead to make this command reusable:

bucket="s3://mybucket"
region="us-east-1"
updateflag="--region $region --acl public-read --metadata-directive REPLACE --cache-control \"public, max-age=86400\""

aws s3 cp $bucket/fileA.js $bucket/fileB.js $updateflag

But this does not work ! It gives Unknown options: max-age=86400" error.

I've tried a few ways around double quotation marks but the only time it works is like this:

updateflag="--region $region --acl public-read --metadata-directive REPLACE"
cacheflag="public, max-age=86400"
aws s3 cp $bucket/em.js $bucket/em.js $updateflag --cache-control "$cacheflag"

What went wrong when I get all options in one variable only ?

UPDATE:

Thanks for pointing out duplicated questions.

I found this question answers my question: Why does shell ignore quotes in arguments passed to it through variables?

I ended up doing the following:

set_cache_control () {
  updateflag=(--region $region --acl public-read --metadata-directive REPLACE --cache-control '"public, max-age=86400"')
  aws s3 cp $bucket/$1 $bucket/$1 "${updateflag[@]}"
}

set_cache_control fileA.js
set_cache_control fileB.js

```

David Lin
  • 13,168
  • 5
  • 46
  • 46
  • 1
    See [BashFAQ #50: I'm trying to put a command in a variable, but the complex cases always fail!](https://mywiki.wooledge.org/BashFAQ/050) Short summary: use a function or array, not a plain variable. Do *not* use `eval`. – Gordon Davisson Nov 16 '18 at 01:12
  • More generally, when you want to re-use a command, define a function. `aws_update () { aws s3 cp "$2" "$3" --region "$1" ...; }`. Call like `aws_update us-east-1 "s3://mybucket/file1" "s3://mybucket/file2" `. – chepner Nov 16 '18 at 01:18
  • Concerning the update: It looks like you're using two levels of quotes around the cache-control string; don't do this, since the inner quotes will be treated as part of the data. Also, I recommend using a function OR an array, not both. Once you're using a function, the array is a useless complication. – Gordon Davisson Nov 16 '18 at 06:55

1 Answers1

0

Bash is separating --cache-control \"public, max-age=86400\" into --cache-control "public, and max-age=86400". So it is not parsing the quotes like you think. Rather, it is passing another argument to the command, which then the aws cli does not know how to handle.

Since Bash is as complicated as it is, and there are a plethora of ways to format strings. You can look at this post dealing with nested quotes in bash.

Edward Minnix
  • 2,889
  • 1
  • 13
  • 26