Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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


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
         result=$(ping -c 1 $node; echo $?)

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

share|improve this question
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
up vote 3 down vote accepted

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

nodes=" "
for node in $nodes
    ping -c 1 $node >/dev/null 2>&1 && nodes_out+=$node
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=" "
$ 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 */ /"); 
      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= nodes=
result=1 node= nodes=
result=1 node= nodes=
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

Another option is to simply use an inverse grep to find all occurrences in the list not matching the host:

for node in $nodes
    if ! `ping -c 1 $node > /dev/null 2>&1`; then 
        nodes="`echo \"$nodes\" | grep -v \"$node\"`"
share|improve this answer

Your Answer


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.