How to ping in linux until host is known?

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...


Solution 1:

A further simplification of Martynas' answer:

until ping -c1 www.google.com >/dev/null 2>&1; do :; done

note that ping itself 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.

Update: I thought of a way to make Control-C exit the ping loop cleanly. This will run the loop in the background, trap the interrupt (Control-C) signal, and kill the background loop if it occurs:

ping_cancelled=false    # Keep track of whether the loop was cancelled, or succeeded
until ping -c1 "$1" >/dev/null 2>&1; do :; done &    # The "&" backgrounds it
trap "kill $!; ping_cancelled=true" SIGINT
wait $!          # Wait for the loop to exit, one way or another
trap - SIGINT    # Remove the trap, now we're done with it
echo "Done pinging, cancelled=$ping_cancelled"

It's a bit circuitous, but if you want the loop to be cancellable it should do the trick.

Solution 2:

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

Solution 3:

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.

Solution 4:

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

Solution 5:

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.