Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

How can I ping a certain address and when found, stop pinging.

I want to use it in a bash script, so when the host is starting up, the script keeps on pinging and from the moment the host is available, the script continues...

share|improve this question

9 Answers 9

up vote 14 down vote accepted

A further simplification of Martynas' answer:

while ! ping -c1 www.google.com &>/dev/null; do :; done

note that ping itself (negated by !) is used as the loop test; as soon as it succeeds, the loop ends. The loop body is empty, with the null command ":" used to prevent a syntax error.

share|improve this answer
1  
perfect! should be accepted answer –  Casey Feb 16 '13 at 23:35

You can do a loop, send one ping and depending on the status break the loop, for example (bash):

while true; do ping -c1 www.google.com > /dev/null && break; done

Putting this somewhere in your script will block, until www.google.com is pingable.

share|improve this answer
1  
This while true and break is the cleaner solution, IMO. –  Dan Carley Jul 17 '09 at 8:26

Ping the target host once. Check if the ping succeeded (return value of ping is zero). If host is not alive, ping again.

The following code can be saved as a file and called with the hostname as argument, or stripped of the first and last line and used as function within an existing script (waitForHost hostname).

The code does not evaluate the cause for failure if the ping does not result in a response, thus looping forever if the host does not exist. My BSD manpage lists the meaning of each return value, while the linux one does not, so I guess this might not be portable, that's why I left it out.

#!/bin/bash

PING=`which ping`

function waitForHost
{
    if [ -n "$1" ]; 
    then
        waitForHost1 $1;
    else
        echo "waitForHost: Hostname argument expected"
    fi
}

function waitForHost1
{
    reachable=0;
    while [ $reachable -eq 0 ];
    do
    $PING -q -c 1 $1
    if [ "$?" -eq 0 ];
    then
        reachable=1
    fi
    done
    sleep 5
}
waitForHost $1
share|improve this answer
    
good solution, thanks! you just forgot a space between 'c' and '1'... –  Sander Versluys Jul 17 '09 at 9:10
1  
-c1 works fine for me on linux and bsd (and solaris, but on solaris -c has another effect) –  Jan Jungnickel Jul 17 '09 at 9:26
    
cool, you've improved your answer, lovely! ;-) –  Sander Versluys Jul 17 '09 at 11:07
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ]; 
   do ping -q -c 1 HOST &> /dev/null; UNREACHEABLE=$?; sleep 1;
done

You may remove sleep 1, it's only here to prevent any flooding problem in case where the host would be reacheable but ping would not exit with code 0.

share|improve this answer

Please see good options at stackoverflow. Here is a sample in bash, you will have to loop over the following code until it returns a successfull ping result.


ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
    echo "192.168.1.1 is up";
else 
    echo "ip is down";
fi

share|improve this answer
    
wow, the answer on that SO link is great! txn –  Sander Versluys Jul 17 '09 at 9:02

I know the question is old... and specifically asks regarding ping, but I wanted to share my solution.

I use this when rebooting hosts to know when I can SSH back into them again. (Since ping will respond for several seconds before sshd is started.)

until nc -vzw 2 $host 22; do sleep 2; done
share|improve this answer
2  
That's exactly what I searched for, thanks! You can even interrupt the call with CTRL+C which is not the case for some other solutions in this thread. –  Alex Jan 19 at 8:58

This will try a given number of times.

t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r

Instead of echoing $r, you can test it and act according to its value:

if ((r)); then echo 'Failed to contact host'; else echo 'Continuing with script'; fi
share|improve this answer

any of the above loops can also be used with fping rather than ping which, IMO, is better suited for use in scripts than ping itself. See fping(1) for details.

while ! fping -q $HOSTNAMES ; do :; done

also useful for testing if machines are up before doing something on them. A simple example:

for h in HOST1 HOST2 HOST3 ; do
  if fping -q $h ; then
     echo -n "$h : "
     ssh $h "uname -a"
  fi
done
share|improve this answer
    
wow cool, i'm such a noob, didn't know that command... txn ;-) –  Sander Versluys Jul 20 '09 at 9:31
    
impossible. how can you not know all of the millions of commands available? :) –  cas Jul 20 '09 at 9:40

I've been using the following function. I like it because I can tell it to stop trying after a while:

#!/usr/bin/env bash

function networkup {
  # Initialize number of attempts
  reachable=$1
  while [ $reachable -ne 0 ]; do
    # Ping supplied host
    ping -q -c 1 -W 1 "$2" > /dev/null 2>&1
    # Check return code
    if [ $? -eq 0 ]; then
      # Success, we can exit with the right return code
      echo 0
      return
    fi
    # Network down, decrement counter and try again
    let reachable-=1
    # Sleep for one second
    sleep 1
  done
  # Network down, number of attempts exhausted, quiting
  echo 1
}

It can be used like this to launch something:

# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
  firefox &
fi
share|improve this answer

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.