Soluzione 1:
Un'ulteriore semplificazione della risposta di Martynas:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
si noti che il ping stesso viene utilizzato come test del ciclo; non appena ha successo, il ciclo termina. Il corpo del ciclo è vuoto, con il comando nullo ":
" utilizzato per prevenire un errore di sintassi.
Aggiornamento:ho pensato a un modo per fare in modo che Control-C esca dal ciclo di ping in modo pulito. Questo eseguirà il loop in background, intrappolerà il segnale di interruzione (Control-C) e interromperà il loop in background se si verifica:
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"
È un po' tortuoso, ma se vuoi che il loop sia cancellabile dovrebbe fare al caso tuo.
Soluzione 2:
So che la domanda è vecchia... e riguarda specificamente ping
, ma volevo condividere la mia soluzione.
Lo uso quando riavvio gli host per sapere quando posso tornare di nuovo in SSH. (Dal ping
risponderà per diversi secondi prima di sshd
è avviato.)
until nc -vzw 2 $host 22; do sleep 2; done
Soluzione 3:
Puoi eseguire un ciclo, inviare un ping e, a seconda dello stato, interrompere il ciclo, ad esempio (bash):
while true; do ping -c1 www.google.com > /dev/null && break; done
Metterlo da qualche parte nel tuo script si bloccherà, fino al www.google.com
è possibile eseguire il ping.
Soluzione 4:
Eseguire il ping dell'host di destinazione una volta. Controlla se il ping ha avuto successo (il valore di ritorno del ping è zero). Se l'host non è attivo, eseguire nuovamente il ping.
Il seguente codice può essere salvato come file e chiamato con l'hostname come argomento, oppure rimosso dalla prima e dall'ultima riga e utilizzato come funzione all'interno di uno script esistente (waitForHost hostname).
Il codice non valuta la causa dell'errore se il ping non genera una risposta, quindi esegue un ciclo infinito se l'host non esiste. La mia manpage BSD elenca il significato di ogni valore restituito, mentre quella di Linux no, quindi immagino che potrebbe non essere portabile, ecco perché l'ho omesso.
#!/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
Soluzione 5:
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ];
do ping -q -c 1 HOST &> /dev/null; UNREACHEABLE=$?; sleep 1;
done
Puoi rimuovere lo sleep 1, è qui solo per prevenire qualsiasi problema di flooding nel caso in cui l'host sia raggiungibile ma il ping non esca con il codice 0.