Shell – Looping a for with variables on a shell script

shellshell-scriptssh

I have the following script that SSH to a server with a key and makes a lot of stuff there.

#!/usr/bin/env bash

ssh -i mykey.pem myuser@SERVER_IP << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH

(which I run it with sh scriptname.sh)

Now I want to to the same in another server, so I've to SSH to two different servers (ip_1 and ip_2) with two different .pem files (mykey1.pem and mykey2.pem).

So far I know how to loop the ips as follows:

#!/usr/bin/env bash

ip_list="ip_1 ip_2"

for ip in $ip_list; do
ssh -i mykey.pem myuser@$ip << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done

but now I would like to loop also to get the proper pem file. How can I archieve this? Maybe with another list? Can someone provide me an elegant solution?

  • ip_1 should use mykey1.pem
  • ip_2 should use mykey2.pem

Thanks in advance

Best Answer

Since you're using bash, you can use associative arrays:

#!/usr/bin/env bash

declare -A ip_list=(["ip_1"]="mykey1.pem" ["ip_2"]="mykey2.pem")

for ip in "${!ip_list[@]}"; do
  ssh -i  "${ip_list[$ip]}" myuser@"$ip" << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done

Note that associative arrays, unlike regular indexed arrays, are not saved in a specific order, so there is no guarantee that ip_1 will be processed before ip_2.


If you need to use a simple, POSIX compatible shell, create a file with the ip and key files, one per line:

$ cat iplist.txt
ip1 mykey1.pem
ip2 mykey2.pem

Then, use this script:

#!/bin/sh

while read -r ip key; do
    ssh -i "$key" myuser@"$ip" << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done 

And run it with:

sh /path/to/script <  /path/to/iplist.txt

But if you go that route, Stéphane's approach is better.

Related Question