Ev sahibi bilinene kadar linux'ta ping nasıl yapılır?


46

Belirli bir adrese nasıl ping atabilirim ve bulunduğunda ping yapmayı nasıl durdurabilirim.

Ben bir bash betiğinde kullanmak istiyorum, bu yüzden, ana bilgisayar başlatıldığında, komut dosyası pinglemeye devam eder ve ana bilgisayar kullanılabilir olduğu andan itibaren, komut dosyası devam eder ...

Yanıtlar:


84

Martynas'ın cevabının başka bir basitleştirmesi:

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

ping'in döngü testi olarak kullanıldığına dikkat edin; başarılı olur olmaz döngü sona erer. Döngü gövdesi boş, :sözdizimi hatasını önlemek için kullanılan " " null komutuyla .

Güncelleme: Control-C'nin ping döngüsünden temiz bir şekilde çıkmasını sağlamanın bir yolunu düşündüm. Bu, döngüyü arka planda çalıştıracak, kesme (Control-C) sinyalini yakalayacak ve gerçekleşirse arka plan döngüsünü öldürecektir:

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"

Biraz dolambaçlı, ancak döngü iptal edilebilir olmasını istiyorsanız hile yapmalı.


6
'Uyku' eklemek için (örneğin, her 5 saniyede bir): süre! ping -c1 www.google.com &> / dev / null; 5 uyu; bitti
lepe

4
Varsayılan pingolarak, ping işleminden vazgeçmeden önce 10 saniye bekleyecektir. Bunu 1 saniyeye düşürmek istiyorsanız kullanabilirsiniz -w1.
Jack O'Connor 19:

2
@ JackO'Connor BSD ping kullanarak, bu bir sermayedir-W1
Luke Exton

Bu cevaba tek sorun SIGINT'i iyi ele almamasıdır. Herhangi bir nedenden dolayı hiçbir zaman bağlanmayacaksa, bunu komut satırından durduramazsınız.
Luke Exton

@LukeExton Bu bash ve ping'in SIGINT'i nasıl kullandıklarından ve nasıl etkileşime girdiklerinden kaynaklanmaktadır ( bu soruya bakınız ). Çok iyi bir çözümüm yok, ama çok fazla şey var: senaryoyu durdurmak için Control-Z kullanın, sonra kill %1onu öldürmek için kullanın.
Gordon Davisson

25

Bir döngü yapabilir, bir ping gönderebilir ve duruma göre döngünün durumuna bağlı olarak, örneğin (bash):

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

Bunu betiğinizde bir yere koymak www.google.com, pingable olana kadar engeller.


2
Bu while trueve breakdaha temiz bir çözüm olan IMO.
Dan Carley

1
@DanCarley Kabul edilen cevabın null komut versiyonunda, birinin bir mola vermesi için bir uyku / bekleyiş yerine geçebileceği ve bunun için daha temiz bir çözüm diyebileceğim için sizinle aynı fikirdeyim. Bu cevapla ilgili diğer sorun, okuyucunun / kullanıcının &&'nin nasıl çalıştığını ve ilk komutun başarısız olması durumunda nasıl çağrılmayacağını anlamasını gerektirmesidir. Bu sadece seninki gibi bir fikir.
Hamid

1
Bu çözüm ile kabul edilen arasında gördüğüm en büyük fark, bunun bulunana kadar "bilinmeyen ana bilgisayar ..." hata mesajını yankılamasıdır. Uyku eklemek için (örneğin her 5 saniyede bir):while true; do sleep 5; ping ...
lepe

20

Sorunun eski olduğunu biliyorum ... ve özellikle de soruyor ping, ancak çözümümü paylaşmak istedim.

Bunu, ne zaman tekrar SSH'ye dönebileceğimi bilmek için ana bilgisayarları yeniden başlatırken kullanırım. ( pingBaşlamadan önce birkaç saniye boyunca cevap verecektir sshd.)

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

2
Tam olarak aradığım şey buydu, teşekkürler! CTRL + C ile aramayı bu konudaki bazı çözümler için geçerli olmayan bir şekilde bile kesebilirsiniz.
Alex

1
Bunun netcat'ın BSD sürümleri için geçerli olduğunu unutmayın. Linux dağıtımlarındaki nmap.org sürümü farklı şekilde uygulanır, bu nedenle -z seçeneği yoktur ve -w seçeneği bir bağlantı bekler ancak başarılı olduğunda kapanmaz. Yine de OSX'te harika çalışıyor.
Paul

Bu yüzden ilk (iyi) cevapta durmuyorsunuz. Asıl sorunun cevabı budur .
Leo

11

Hedef ana bilgisayara bir kez ping işlemi yapın. Ping'in başarılı olup olmadığını kontrol edin (ping'in dönüş değeri sıfırdır). Eğer ev sahibi canlı değilse, tekrar ping işlemi yapın.

Aşağıdaki kod bir dosya olarak kaydedilebilir ve ana makine adı ile argüman olarak çağrılabilir veya ilk ve son satırdan sıyrılabilir ve varolan bir komut dosyasında işlev olarak kullanılabilir (waitForHost ana bilgisayar adı).

Ping, bir yanıtla sonuçlanmazsa, başarısızlığın nedenini değerlendirmez; bu nedenle, ana bilgisayar yoksa sonsuza kadar döngü oluşturur. BSD sayfamda her bir iade değerinin anlamı listeleniyor, linux ise değil, bu yüzden taşınabilir olmayabilir, bu yüzden dışarıda bıraktım.

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

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

1. uykuyu kaldırabilirsiniz, yalnızca ana makinenin erişebileceği ancak ping kodu 0 ile çıkmayacaksa, taşma sorununu önlemek için burada.


4

Lütfen stackoverflow'ta iyi seçeneklere bakın . İşte bash bir örnek, başarılı bir ping sonucu döndürene kadar aşağıdaki kodun üzerinden döngü gerekir.


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


3

Yukarıdaki halkalardan herhangi biri, IMO, ping komutunun kendisinden ziyade betiklerde daha uygun olan ping yerine fping ile de kullanılabilir. Detaylar için fping (1) bölümüne bakınız.

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

Makinelerin üzerinde bir şey yapmadan önce hazır olup olmadıklarını test etmek için de yararlıdır. Basit bir örnek:

HOST1 HOST2 HOST3'teki h için; yap
  eğer -q $ h ile çarpıyorsa; sonra
     echo -n "$ h:"
     ssh $ h "uname -a"
  fi
tamam

1

Bu, verilen sayıda çalışacaktır.

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

Yankı yerine $rtest edebilir ve değerine göre hareket edebilirsiniz:

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

1

SIGINT'i BSD ping'inde güzelce kullanmak için.

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"

işlev olarak

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
}

0

Aşağıdaki işlevi kullanıyorum. Sevdim çünkü bir süre sonra denemeyi bırakmasını söyleyebilirim:

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

Bir şey başlatmak için bu şekilde kullanılabilir:

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

0

Genel olarak veritabanımın veya diğer sunucumun gelmesini beklemek istiyorum, ancak çok uzun süre beklemek istemiyorum . Aşağıdaki kod 10 saniye bekler, ardından sunucu süre içinde görünmediyse çıkış kodunu ayarlar.

Eğer sunucu zaman sınırından önce belirirse, döngü kısa devre olacaktır, böylece bir sonraki kod bitini çalıştırabilir.

for i in `seq 1 10`; do date ; sleep 1 ; ping -c1 ${HOST} &>/dev/null && break ; done

0

Gordon Davisson'ın cevabına bir başka gelişme:

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

'$ ()' çevreleyen bir alt kabuk başlatılır ve bu nedenle, sunucunun kullanılabilir olmaması durumunda döngüyü sonlandırmak için Control-C kullanabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.