Bash question: working with an array of previously set variable strings

while i've used arrays to work with variables, i've never used them to loop through a set of strings and wanted to ask the community for some feedback or assistance.

let me be specific. here's my code:

# URL port Variables
port2195=`nc -z $url2195 2195`
port2196=`nc -z $url2196 2196`
port5223=`nc -z $url5223 5223`
port443=`nc -z $url443 443`

# Set array
range=( port2195 port2196 port5223 port443 )

echo ""
echo "Now checking the ports..."
echo ""

for i in "${range[@]}"
do
	if [[ "$i" = *succeeded* ]];
	then
		echo "SUCCESS: $i is open/working."
	else
		echo "FAILURE: $i is NOT open/working."
	fi	
done

this code works just fine.... just not in the way that i want!

the script is passing the members of the array exactly as i've typed them, one at a time: port2195, port2196, port5223, etc.

what i'm trying to do and failing to achieve is to pass each member of the array as a previously established string: $port2195, $port2196, $port5223, etc.

changing the names of each member of the array to include a "$", doesn't work, neither does adding a second "$" into the if statement.

i'm not even sure if you can pass strings via an array but, if it is possible, much obliged for someone to drop me a few pointers.

cheers,

There's at least two workarounds for that assignment statement:

- eval range=( $port2195 $port2196 $port5223 $port443 ) # deprecated as eval can be dangerous (see many a post in these forums)
- range=( $(echo $port2195 $port2196 $port5223 $port443 ))

How about something like this:

url[2195]=foo
url[2196]=bar
url[5223]=baz
url[443]=bay

range="2195 2196 5223 443"
echo ""
echo "Now checking the ports..."
echo ""
for i in $range
do
  if [[ $(nc -z "${url}" $i) == *succeeded* ]];
  then
    echo "SUCCESS: $i is open/working."
  else
    echo "FAILURE: $i is NOT open/working."
  fi	
done

i appreciate the quick response!

if the range command (which i'd never heard of) is more effective at passing a list of values than the array command, why bother using the array command? it certainly seems like range is able to accomplish what array can do and then some.

the script works as i'd intended now, so to both of you, again: thank you.

There is no range command.

range="2195 2196 5223 443"

A string with spaces is assigned to a simple variable.

for i in $range

The unquoted $range lets the shell break the string into tokens, so there is a loop over all tokens.
Of course you can directly do

for i in 2195 2196 5223 443

---------- Post updated at 04:13 AM ---------- Previous update was at 04:03 AM ----------

An alternative technique:

while read url port
do
  if [[ $(nc -z "$url" "$port") == *succeeded* ]]
  then
    echo "SUCCESS: $port is open/working."
  else
    echo "FAILURE: $port is NOT open/working."
  fi
done << URL_PORT
foo 2195
bar 2196
baz 5223
bay 443
URL_PORT

It looks like you have to bind stderror with stdout to get the output into a variable.
2>&1

# URL port Variables

port2195=`nc -z $url2195 2195 2>&1`
port2196=`nc -z $url2196 2196 2>&1`
port5223=`nc -z $url5223 5223 2>&1`
port443=`nc -z $url443 443 2>&1`
port25=`nc -z localhost 25 2>&1`

Use $var so they will get expanded by bash.

# Set array
range=( $port2195 $port2196 $port5223 $port443 $port25 )

If you want an array for record keeping or logging or whatever, building the array in a loop might be better...

url[2195]=localhost
url[2196]=localhost
url[5223]=localhost
url[443]=localhost
url[25]=localhost


port[2195]=""
port[2196]=""
port[5223]=""
port[443]=""
port[25]=""

echo
echo "Now checking the ports..."
echo

# fill port array in a loop
for i in ${!url
[*]}  # !url returns the index of the array, not the value.
do
    port[$i]=$(nc -zv ${url[$i]} $i 2>&1)
    if [[ ${port[$i]} =~ *succeeded* ]]; then
        echo "SUCCESS: port $i is open/working."
    else
        echo "FAILURE: port $i is NOT open/working."
    fi
done