user3558925
user3558925

Reputation: 143

Bash: Breaking out of IF loop in FOR loop

I am trying to combine a FOR loop (that iterates over IP addresses) and an IF loop (that uses nc to check for a successful ssh connection before moving on).

I have an array ${INSTANCE_IPS[@]} with the IP addresses in it (at the moment it contains 2 IP Addresses). Here is the code:

while [ $ITERATION -le 30 ]
do
    for instance in ${INSTANCE_IPS[@]}
    do    
        nc -w 2 $instance 22 > /dev/null
            if [ $? -eq 0 ]
            then echo "connection succeeded to $instance"
            else
                ITERATION=$((ITERATION+1))
                echo ITERATION=$ITERATION
                echo "[info] connection to $instance unsuccessful. trying again. iteration=$ITERATION"
                sleep 20
            fi
    done
done

The 'else' statement in the IF loop works fine. It is the 'then' statement I am having problems with... I don't know how to break out of the IF loop once the connections are successful. Here's an example output when I run the above:

connection succeeded to 10.11.143.171
connection succeeded to 10.11.143.170
connection succeeded to 10.11.143.171
connection succeeded to 10.11.143.170
connection succeeded to 10.11.143.171
connection succeeded to 10.11.143.170

If I use break after then echo "connection succeeded to $instance then it only iterates through 1 IP address and never breaks out:

connection succeeded to 10.11.143.171
connection succeeded to 10.11.143.171
connection succeeded to 10.11.143.171

Ideally I think the best thing to do would be to query the number of elements in the array, then perform a netcat connection an increment some value by 1 until it equals the number of elements in the array, but I'm really not sure how to dot that.

Any help is appreciated :) Please let me know if you need any more information.

Cheers

Upvotes: 1

Views: 5126

Answers (1)

that other guy
that other guy

Reputation: 123470

Reformulate your logic. You can't break if something succeeds, because you don't know whether another item might fail.

Instead, keep a flag saying whether you've successfully gone through all of them, and set it to false if something fails. At this point, you can also break and wait.

ITERATION=0
all_succeeded=false
while [ "$all_succeeded" = "false" -a $ITERATION -le 30 ]
do
    all_succeeded=true
    for instance in ${INSTANCE_IPS[@]}
    do    
        nc -w 2 $instance 22 > /dev/null
        if [ $? -eq 0 ]
        then 
          echo "connection succeeded to $instance"
        else
          all_succeeded=false
          echo "[info] connection to $instance unsuccessful."
          sleep 20
          break
        fi
    done
    let ITERATION++
done

if [ "$all_succeeded" = "true" ]
then
  echo "It worked"
else
  echo "Giving up"
fi

Upvotes: 6

Related Questions