Vraag Hoe te pingelen in linux totdat host bekend is?


Hoe kan ik een bepaald adres pingen en wanneer het gevonden is, stop dan met pingen.

Ik wil het gebruiken in een bash-script, dus wanneer de host opstart, blijft het script pingen en vanaf het moment dat de host beschikbaar is, gaat het script verder ...


42
2017-07-17 07:45


oorsprong




antwoorden:


Een verdere vereenvoudiging van het antwoord van Martynas:

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

merk op dat ping zelf wordt gebruikt als de lustest; zodra het lukt, eindigt de lus. Het luslichaam is leeg, met het null-commando ":"gebruikt om een ​​syntaxisfout te voorkomen.

Update: ik dacht aan een manier om Control-C de ping-lus netjes te laten afsluiten. Dit zal de lus op de achtergrond uitvoeren, het interrupt (Control-C) signaal vangen en de achtergrondlus doden als het gebeurt:

ping_cancelled=false    # Keep track of whether the loop was cancelled, or succeeded
until ping -c1 "$1" &>/dev/null; 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"

Het is een beetje omslachtig, maar als je wilt dat de lus annuleerbaar is, zou het de slag moeten slaan.


77
2017-07-17 23:16



Om 'slaap' toe te voegen (bijvoorbeeld elke 5 sec): terwijl! ping -c1 www.google.com &> / dev / null; slaap 5; gedaan - lepe
Perfect! Werkt ook op Mac OSX. - Bart Kummel
Standaard ping wacht 10 seconden voordat hij de ping beëindigt. Als u dit wilt reduceren tot 1 seconde, kunt u gebruiken -w1. - Jack O'Connor
@ JackO'Connor Met behulp van BSD ping is dit een kapitaal -W1 - Luke Exton
Mijn enige probleem met dit antwoord is dat het SIGINT niet goed aanpakt. U kunt dit niet stoppen vanaf de opdrachtregel, als het om welke reden dan ook nooit verbinding zal maken. - Luke Exton


U kunt een lus uitvoeren, één ping verzenden en afhankelijk van de status de lus doorbreken, bijvoorbeeld (bash):

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

Als u dit ergens in uw script plaatst, wordt dit geblokkeerd totdat www.google.com is pingbaar.


22
2017-07-17 08:01



Deze while true en break is de schonere oplossing, IMO. - Dan Carley
@DanCarley Ik ga het niet met je eens zijn om de reden dat in het geaccepteerde antwoord, de null-commandoversie, een slaap / wachttijd kan worden vervangen om je CPU een pauze te geven, en in dat geval zou ik het de schonere oplossing noemen. Het andere probleem met dit antwoord is dat het de lezer / gebruiker vereist om te begrijpen hoe && werkt, en hoe dat als het eerste commando faalt, het niet zal worden aangeroepen. Dit is slechts een mening, zoals de uwe. - Hamid
Het belangrijkste verschil dat ik zie tussen deze oplossing en de geaccepteerde oplossing, is dat deze de foutmelding "onbekende host ..." weergeeft tot het moment is gevonden. Toevoegen slaap (bijvoorbeeld elke 5 sec): while true; do sleep 5; ping ... - lepe


Ik weet dat de vraag oud is ... en specifiek vraagt ​​naar ping, maar ik wilde mijn oplossing delen.

Ik gebruik dit bij het opnieuw opstarten van hosts om te weten wanneer ik SSH er weer in kan laden. (Sinds ping zal enkele seconden eerder reageren sshd is begonnen.)

until nc -vzw 2 $host 22; do sleep 2; done

17
2017-10-11 14:37



Dat is precies wat ik zocht, bedankt! U kunt het gesprek zelfs onderbreken met CTRL + C, wat niet het geval is voor sommige andere oplossingen in deze thread. - Alex
Let op dit werkt voor BSD-versies van netcat. De nmap.org-versie in Linux-distributies is anders geïmplementeerd, dus de optie -z bestaat niet en de optie -w wacht op een verbinding maar wordt niet afgesloten wanneer deze succesvol is. Werkt echter prima in OSX. - Paul


Ping de doelgastheer eenmaal. Controleer of de ping geslaagd is (de retourwaarde van ping is nul). Als de host niet leeft, pingt u opnieuw.

De volgende code kan worden opgeslagen als een bestand en wordt aangeroepen met de hostnaam als argument, of ontdaan van de eerste en laatste regel en gebruikt als functie binnen een bestaand script (hostnaam waitForHost).

De code evalueert de oorzaak van de fout niet als de ping geen antwoord oplevert, dus voor altijd in een lus als de host niet bestaat. Mijn BSD-manpage somt de betekenis van elke retourwaarde op, terwijl de linux niet, dus ik denk dat dit misschien niet draagbaar is, daarom heb ik het weggelaten.

#!/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

11
2017-07-17 07:58





UNREACHEABLE=1;
while [ $UNREACHEABLE -ne "0" ]; 
   do ping -q -c 1 HOST &> /dev/null; UNREACHEABLE=$?; sleep 1;
done

U kunt slaap 1 verwijderen, alleen hier om overstromingsproblemen te voorkomen in het geval dat de host bereikbaar zou zijn, maar ping niet zou afsluiten met code 0.


9
2017-07-17 08:09





Zie alstublieft goede opties op stackoverflow. Hier is een voorbeeld in bash, je zult de volgende code moeten herhalen totdat het een succesvol ping resultaat oplevert.


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


4
2017-07-17 08:00





een van de bovenstaande lussen kan ook worden gebruikt met fping in plaats van ping, die, IMO, beter geschikt is voor gebruik in scripts dan zelf ping. Zien fping (1) voor details.

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

ook handig om te testen of machines in gebruik zijn voordat je iets op ze gaat doen. Een eenvoudig voorbeeld:

voor h in HOST1 HOST2 HOST3; do
  als fping -q $ h; dan
     echo -n "$ h:"
     ssh $ h "uname -a"
  fi
gedaan

3
2017-07-18 23:25





Dit zal een bepaald aantal keren proberen.

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

In plaats van echoën $r, je kunt het testen en handelen volgens de waarde ervan:

if ((r)); then echo 'Failed to contact host'; else echo 'Continuing with script'; fi

1
2018-06-26 02:06