Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have written a command that output a list of hostnames, e.g. :

clab148node11
clab148node12
clab148node15
clab148node16

Now, I would like to remove those nodes that do not respond to ping. For now I have something like this :

for node in $nodes
do
         result=$(ping -c 1 $node; echo $?)
done

Now how do I remove nodes that have the $result different than 0 ?

share|improve this question
2  
Is it a requirement to remove from the list? I prefer to build a new list instead: error=(); for node in $nodes; do ping -c 1 $node || error+=($node); done –  manatwork Feb 5 '13 at 10:28
    
@manatwork Well it's also a solution but if it's possible to be done without then I would like to see it as well. –  Patryk Feb 5 '13 at 10:33

2 Answers 2

up vote 2 down vote accepted

I'd prefer to build a new list and replace an old one with a new:

nodes="127.0.0.1 1.2.3.4 1.2.3.4 "
nodes_out=
for node in $nodes
do 
    ping -c 1 $node >/dev/null 2>&1 && nodes_out+=$node
done
nodes=$nodes_out
share|improve this answer

like @manatwork said, it looks simpler and safer to build a new list with the valid nodes.

However, as "$nodes" is evaluated before the first iteration of the for loop, it should be possible to change it during that same loop:

$ nodes="127.0.0.1 1.2.3.4 1.2.3.4 "
$ for node in $nodes; do
      result=$(ping -c 1 $node >/dev/null 2>/dev/null; echo $?);
      if [ "$result" -ne 0 ]; 
      then    nodes=$(echo $nodes | sed -e "s/ *$node */ /"); 
      fi;
      echo result=$result node=$node nodes=$nodes ;    
  done ;

Notice : my sed replace [space]$node[space] or $node[space] or [space]$node to work in all cases depending on the position of $node in the $nodes list (If its in the middle, or the first or the last element, space(s) before and after it will be either present or not). And it only replace 1 occurence at a time, but you could add a final /g to get rid of all occurences at once.

This outputs:

result=0 node=127.0.0.1 nodes=127.0.0.1 1.2.3.4 1.2.3.4
result=1 node=1.2.3.4 nodes=127.0.0.1 1.2.3.4
result=1 node=1.2.3.4 nodes=127.0.0.1
share|improve this answer
    
you can use nodes=${nodes/$node} instead expression with sed in bash, ksh, etc. spaces don't matter in such list. –  rush Feb 5 '13 at 11:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.