Loop Through Variables
Use an array.
#! /bin/bash
servers=( 192.xxx.xxx.2 192.xxx.xxx.3
192.xxx.xxx.4 192.xxx.xxx.5
192.xxx.xxx.6 192.xxx.xxx.7
)
for server in "${servers[@]}" ; do
echo "$server"
done
As the other answers point out, an array is the most convenient way to do this. However, for completeness, the exact thing you are asking for is indirect expansion. Rewritten as follows, your sample will also work using this method:
#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"
for ((i=1; i<7; i++))
do
servervar="SERVER$i"
echo "${!servervar}"
done
If you're OK with just putting the list of IP addresses in the the for
loop, then you might also consider simply using some brace expansions to iterate over whatever you need:
#!/bin/bash
for server in \
192.xxx.xxx.{2..7} \
192.yyy.yyy.{42..50} \
192.zzz.zzz.254
do
echo "$server"
done
But if you need to reuse the (possibly brace-expanded) list, then using the list to initialize an array would be the way to go:
#!/bin/bash
servers=(
192.xxx.xxx.{2..7}
192.yyy.yyy.{42..50}
192.zzz.zzz.254 )
for server in "${servers[@]}"
do
echo "$server"
done
While I would probably go with one of the array answers myself, I’d like to point out that it is possible to loop over names directly. You can do
for name in "${!SERVER*}"; do
echo "${!name}"
done
or, in 4.3 and up, you can use a nameref
:
declare -n name
for name in "${!SERVER*}"; do
echo "$name"
done
Hat tip ilkkachu for the < 4.3 solution.