16

I'm getting a list of EC2 instances and then trying to loop through them but for some reason I'm not able to get the loop to work.

output="$(aws ec2 describe-instances --filters 'Name=tag:Environment,Values=development' --query '[Reservations[*].Instances[*].PublicDnsName]' --output text)"

echo $output displays something like:

ec2-55-55-555-555.eu-west-1.compute.amazonaws.com
ec2-66-66-666-666.eu-west-1.compute.amazonaws.com

Then I create an array like this:

instances=(${output//'\n'/ })

echo ${instances[0]} and echo ${instances[1]} gives the correct output.

And then try to iterate through the array:

for i in $instances; do echo instance: "$i"; done

But I get:

instance: ec2-55-55-555-555.eu-west-1.compute.amazonaws.com ec2-66-66-666-666.eu-west-1.compute.amazonaws.com

Instead of:

instance: ec2-55-55-555-555.eu-west-1.compute.amazonaws.com
instance: ec2-66-66-666-666.eu-west-1.compute.amazonaws.com

What am I doing wrong? And is there a better way to loop through the results, maybe rather using the json output format?

7
  • Try to run for i in $output; do echo $i; done Commented Apr 6, 2016 at 13:38
  • 1
    I've tried that, it echos the whole variable. Doesn't split the lines. Commented Apr 6, 2016 at 13:41
  • 2
    what about: for i in "${instances[@]}"; do ...? Commented Apr 6, 2016 at 13:49
  • Just add a line separator with: for i in $instances; do echo instance: "$i"$'\n'; done Commented Apr 6, 2016 at 14:14
  • 1
    Also see Bash FAQ 001 for how to properly read line-by-line from a stream. Commented Apr 6, 2016 at 14:53

5 Answers 5

27

I am not sure if you got an answer for this question. Will this help?

for dns in $(aws ec2 describe-instances --region ap-northeast-1 --query 'Reservations[*].Instances[*].PublicDnsName' --output text) ; do echo $dns ; done
Sign up to request clarification or add additional context in comments.

1 Comment

How can we do this with multiple columns?
1

For windows cli:

aws ec2 describe-instances --query "Reservations[].Instances[].InstanceId" > instances

FOR /f %i IN (instances) DO aws ec2 terminate-instances --instance-ids %i

2 Comments

The question asks for a bash script
But useful. Vote up.
1

This also works for me, add it to a bash array:

for instance in $(aws ec2 describe-instances --filters "Name=tag:Application,Values=yourValue" "Name=tag:Environment,Values=development" --query 'Reservations[*].Instances[*].InstanceId' --output text); do envInstances+=(${instance}); done

for i in ${envInstances[@]}; do echo "hello $i"; done

hello i-instance1
hello i-instance12
hello i-instance16

Comments

1

Not sure if you just gave up, but in BASH, better to just do this:

OUTPUT=($(aws ec2 describe-instances --filters 'Name=tag:Environment,Values=development' --query '[Reservations[].Instances[].PublicDnsName]' --output text))

then (if you want a count)

echo "${#OUTPUT[@]} instances found."

Good luck!

1 Comment

This solved a similar issue for me. The key is to use parentheses around the command substitution "$()": var=($(command))
0

One liner using xargs:

aws ec2 describe-instances --filters 'Name=tag:Environment,Values=development' --query '[Reservations[*].Instances[*].PublicDnsName]' --output text | xargs --no-run-if-empty -n1 echo 'Instance:'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.