Comment puis-je cingler une certaine adresse et une fois trouvé, arrêtez de cingler.
Je veux l'utiliser dans un script bash, donc au démarrage de l'hôte, le script continue de cingler et à partir du moment où l'hôte est disponible, le script continue ...
Une nouvelle simplification de la réponse de Martynas:
until ping -c1 www.google.com >/dev/null 2>&1; do :; done
notez que le ping lui-même est utilisé comme test de boucle; dès qu'il réussit, la boucle se termine. Le corps de la boucle est vide, avec la commande null ":
"utilisé pour éviter une erreur de syntaxe.
Mise à jour: J'ai pensé à un moyen de faire en sorte que Control-C quitte la boucle ping proprement. Cela exécutera la boucle en arrière-plan, interceptera le signal d'interruption (Control-C) et tuera la boucle d'arrière-plan si elle se produit:
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"
C'est un peu détourné, mais si vous voulez que la boucle soit annulable, cela devrait faire l'affaire.
Vous pouvez faire une boucle, envoyer un ping et selon le statut rompre la boucle, par exemple (bash):
while true; do ping -c1 www.google.com > /dev/null && break; done
Mettre cela quelque part dans votre script bloquera, jusqu'à ce que www.google.com
est pingable.
Je sais que la question est ancienne ... et demande spécifiquement concernant ping
, mais je voulais partager ma solution.
Je l'utilise lors du redémarrage des hôtes pour savoir quand je peux à nouveau les SSH. (Puisque ping
répondra pendant plusieurs secondes avant que sshd
ne démarre.)
until nc -vzw 2 $Host 22; do sleep 2; done
Envoyez une requête ping à l'hôte cible une fois. Vérifiez si le ping a réussi (la valeur de retour de ping est zéro). Si l'hôte n'est pas vivant, exécutez à nouveau une commande ping.
Le code suivant peut être enregistré en tant que fichier et appelé avec le nom d'hôte comme argument, ou supprimé de la première et de la dernière ligne et utilisé comme fonction dans un script existant (nom d'hôte waitForHost).
Le code n'évalue pas la cause de l'échec si le ping n'aboutit pas à une réponse, bouclant ainsi indéfiniment si l'hôte n'existe pas. Ma page de manuel BSD répertorie la signification de chaque valeur de retour, contrairement à celle de Linux, donc je suppose que cela pourrait ne pas être portable, c'est pourquoi je l'ai laissé de côté.
#!/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
UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ];
do ping -q -c 1 Host &> /dev/null; UNREACHEABLE=$?; sleep 1;
done
Vous pouvez supprimer sleep 1, c'est seulement ici pour éviter tout problème d'inondation au cas où l'hôte serait accessible mais le ping ne sortirait pas avec le code 0.
Veuillez voir les bonnes options sur stackoverflow . Voici un exemple en bash, vous devrez parcourir le code suivant jusqu'à ce qu'il retourne un résultat ping réussi.
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
n'importe laquelle des boucles ci-dessus peut également être utilisée avec fping plutôt qu'avec ping qui, IMO, est mieux adapté pour une utilisation dans les scripts que ping lui-même. Voir fping (1) pour plus de détails.
while ! fping -q $HOSTNAMES ; do :; done
également utile pour tester si les machines sont en marche avant de faire quelque chose sur elles. Un exemple simple:
pour h dans Host1 Host2 Host3; faire si fping -q $ h; alors echo -n "$ h:" ssh $ h "uname -a" fi fait
Pour bien gérer le ping SIGINT sur BSD.
Host=google.com NO=1; while [ $NO -ne 0 ]; do ping -W1 -c1 $Host &>/dev/null; NO=$?;echo "$(date) ($Host) $NO" ; done; echo "$(date) ($Host) reachable"
en tant que fonction
ping_until(){
local NO=1
while [ $NO -ne 0 ]; do
ping -W1 -c1 $1 &>/dev/null; NO=$?
# Optionally block ICMP flooding
# sleep 1
echo "$(date) ($1) ($NO)"
done
}
Cela va essayer un certain nombre de fois.
t=4; c=0; r=0; until ping -c 1 hostname.com >/dev/null 2>&1 || ((++c >= t)); do r=$?; done; echo $r
Au lieu de faire écho à $r
, vous pouvez le tester et agir en fonction de sa valeur:
if ((r)); then echo 'Failed to contact Host'; else echo 'Continuing with script'; fi
Pour les utilisateurs de macOS, ping
a l'option -o
spécifiquement pour cela:
-o Exit successfully after receiving one reply packet.
La commande est donc simple:
ping -o www.google.com
Il renvoie 0 lorsque l'hôte a été envoyé une fois avec succès.
En général, je veux attendre que ma base de données ou un autre serveur apparaisse, mais je ne veux pas attendre trop longtemps. Le code suivant attend 10 secondes, puis définit le code de sortie si le serveur n'est pas apparu dans le délai imparti.
Si le serveur apparaît avant la limite de temps, la boucle sera court-circuitée afin que le bit de code suivant puisse s'exécuter.
for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${Host} &>/dev/null && break ; done
J'utilise la fonction suivante. Je l'aime parce que je peux lui dire d'arrêter d'essayer après un certain temps:
#!/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
}
Il peut être utilisé comme ceci pour lancer quelque chose:
# Start-up a web browser, if network is up
if [ $(networkup 60 www.google.com) -eq 0 ]; then
firefox &
fi
Une autre amélioration de la réponse de Gordon Davisson:
until $(ping -c1 www.google.com &>/dev/null); do :; done
avec le "$ ()" environnant, un sous-shell est démarré et vous pouvez donc utiliser Control-C pour terminer la boucle dans le cas où l'hôte ne deviendrait pas disponible.