Skip to content
Advertisement

Iterate through commands and execute in bash

I wrote a script that transfers a new key to my AWS instances. The script executes with no errors, but when I check the ~/.ssh/authorized_keys file on the instance, I do not see the new SSH key.

Here is the script:

aws_instances=(             
                "ssh -i "priv.pem" ubuntu@99.99.99.1" #server1
                "ssh -i "priv.pem" ubuntu@99.99.99.2" #server2
                "ssh -i "priv.pem" ubuntu@99.99.99.3" #server3
              )
IFS=""
for t in ${aws_instances[@]}; do
  cat ~/newKey.pub | eval $t  'cat >> ~/.ssh/authorized_keys && echo "Key copied"'
done

It does print out “Key copied”

I have changed the ip addresses of the servers.

If I just execute the following command, it works.

cat ~/newKey.pub | ssh -i "priv.pem" ubuntu@99.99.99.1  'cat >> ~/.ssh/authorized_keys && echo "Key copied"'

What is wrong with my script?

Advertisement

Answer

You need extra quotes around the second eval argument.

e.g.:

cat ~/newKey.pub | eval $t  "'"'cat >> ~/.ssh/authorized_keys && echo "Key copied"'"'"

The Problem is that the single quotes get lost on the first call to eval, so the command it tries to execute will be

ssh -i "priv.pem" ubuntu@99.99.99.1 cat >> ~/.ssh/authorized_keys && echo "Key copied"

which just appends the output of your ssh command to your local authorized_keys file instead of adding the key to the remote host.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement