1

I'm try use the AWS CLI to send an SES email, but this question is more related to Bash variables, IFS, and expansion than anything AWS related.

My recipients variable is formatted as follows:

TO="\"My Name<name@email.com>\" \"Your Name<you@email.com>\""

The --to parameter expects a space delimited list. If I don't use the $TO variable and just do

aws ses send-email --to "My Name<name@email.com>" "Your Name<you@email.com>"

everything works just fine. But if I do any of the following, I get errors from either the --to parameter treating $TO as a single string or splitting on the spaces in the "name" of the recipient:

aws ses send-email --to "$TO"
aws ses send-email --to $(echo "$TO")
aws ses send-email --to "$(echo "$TO")"
sed ses send-email --to "$(echo $TO)"

How do I get the --to parameter to treat my variable as a space delimited list but still respect the quotes wrapping each email address?

EDIT:

This is running in a docker container where I'm getting arguments passed in as strings, one of them is -email \"My Name<name@email.com>\" where the argument to email could be 1 or many email addresses. I'm isolating the email addresses like this:

if [[ "$ITEM" =~ ^-email[[:space:]]+(.*)$ ]]; then
  EMAIL=("${BASH_REMATCH[1]}")
fi

In that context, the $EMAIL variable is a single string, which doesn't lend itself well to the use arrays approach. If I do

if [[ "$ITEM" =~ ^-email[[:space:]]+(.*)$ ]]; then
  EMAIL=($(echo ${BASH_REMATCH[1]}"))
fi

Then email ends up as an array with the string separated by spaces, so it breaks up the parts inside the embedded quotes. Thus, were I to set the $TO variable manually, then no problem, but since it's coming in as a parameter, I think this is more complicated. I do have the ability to specify the delimiter that should be use between email addresses if that might make it easier to parse? Maybe read the whole argument as a string and then split it on the special delimiter like a comma to get it into an array? Or make the delimiter the " " pattern?

mhaken
  • 1,075
  • 4
  • 14
  • 28
  • To "respect" the quotes, they need to be parsed as syntax. Treating data as syntax is, as a rule, extremely dangerous -- if you feed content back through the parser from the beginning (as with `eval`), then a recipient name that included `$(rm -rf ~)` would result in the person maintaining the box running the code having a *very* bad day. – Charles Duffy Sep 22 '17 at 17:16
  • So `-email \"My Name\"` is passed in as a single string? That's a very unfortunate design (as opposed to passing in each final argument as a separate argument up-front), but we *do* actually already have questions describing how to handle it in the knowledgebase already. (The best practice approach is to use `xargs` to split into a NUL-delimited list, and then read that into an array). – Charles Duffy Sep 22 '17 at 18:25
  • I'm sitting down for lunch right this minute (and have a meeting directly following), but I'll edit the duplicate list to be appropriate in light of the edits and clarification when I'm back. – Charles Duffy Sep 22 '17 at 18:26
  • Yea, unfortunately there's a multitude of arguments that are being passed to the docker container via the entry point, not just `-email`, and the only good way to group and identify them was passing each arg as its own string, even if it had multiple values. – mhaken Sep 22 '17 at 18:43
  • so, I'm not sure I agree about "only good way". If it's two categories, for instance, it's fairly common to use a sigil: `./yourprogram --type1-arg "foo" --type1-option -- --type2-arg "bar"`. Or `./yourprogram --type1-arg --foo --type1-arg something --type1-arg --bar --type2-arg --baz`, then assembling the type-1 array to `--foo something --bar` and the type-2 array to `--baz`. – Charles Duffy Sep 22 '17 at 19:00
  • I've added https://stackoverflow.com/questions/26067249/bash-reading-quoted-escaped-arguments-correctly-from-a-string to the list of dupes, the answer to which should be applicable to your use case. – Charles Duffy Sep 22 '17 at 19:01
  • @CharlesDuffy, I ended up with this from that duplicate: array=( ) while IFS= read -r -d ''; do array+=( "$REPLY" ) done < <(xargs printf '%s\0' <<<"$ARGS") Can you explain though why the '' delim correctly interprets the content between single quotes or double quotes? – mhaken Sep 22 '17 at 19:17
  • `swap` is the program the OP there is defining, so if you replace it with your `aws ses send-email`, then there you are. – Charles Duffy Sep 22 '17 at 19:18

0 Answers0