2015-11-23 17 views
7

Napisałem ten skrypt bash, aby otrzymać powiadomienie, gdy Internet stanie się dostępny, ale nie rozumiem wielu rzeczy, które się dzieją. Oto scenariusz:Skrypt Bash do powiadamiania, gdy dostęp do Internetu jest

while ! ping 8.8.8.8 -c 1 2&> /dev/null ; do true; done; 
  • Opcja -c 1 mówi ping że chcę wysłać tylko jeden pakiet.
  • Jest tam 2&> /dev/null, ponieważ nie chcę widzieć danych wyjściowych.
  • true jest tam, ponieważ bash nie zaakceptował składni do;.
  • warunkiem zakończenia jest ! ping ..., ponieważ ping zwraca kod statusu niezerowy, gdy nie jest odbierany żaden pakiet przed niektórymi timeout.

Zamierzeniem było zakończenie tej pętli po pomyślnym zakończeniu ping, a emulator terminala automatycznie wyśle ​​do mnie powiadomienie.


Problemy

  • Komenda ta nie kończy się nawet wtedy, gdy Internet staje się dostępny.
  • Próba zabicia polecenia przy użyciu ctrl + C nie działa. Myślę, że to zabicie podkomunikatu ping zamiast całego polecenia.
  • Usunięcie tylko 2&> /dev/null powoduje, że wszystko działa, z wyjątkiem drobnego problemu, który wypisuje wyjście do terminala.

Pytania

  1. Co jest nie tak z moją komendą?
  2. Jak dokładnie emulatory terminala reagują na ctrl + C?
  3. Dlaczego usunięcie 2&> /dev/null powoduje, że działa?

Pamiętaj, że już dokonałem zwrotu. Niemniej jednak chcę zrozumieć nieco więcej.

f() { while ! ping 8.8.8.8 -c 1 ; do true; done; }; f 2&> /dev/null 
+1

Moja wersja 'ping' oczekuje' ping -c 1 8.8.8.8'. Pluse-uno do zbadania twojego problemu! Powodzenia. – shellter

Odpowiedz

8

Prawidłowe operatora przekierowania jest &> nie 2&>. Ta 2 jest analizowana jako osobny argument dla ping, a ponieważ pingowanie 2 nigdy się nie powiedzie, pętla nigdy nie istnieje.

+0

* Moja wina. Nie udało mi się użyć tej bardziej złożonej składni "2> i 1". * Nie wyjaśniasz problemu 'Ctrl + C'. Czy 'Ctrl + C' zabija polecenie ping zamiast pętli? ponieważ z twoją sugestią ('&>'), polecenie jest w stanie przerwać ctrl-c, gdy nie ma sieci (gdy ping nie działa). –

+1

Ctrl + C wysyła przerwanie do bieżącego zadania pierwszego planu, którym może być 'ping', lub może to być powłoka, w zależności od tego, kiedy faktycznie ją wpiszesz. – chepner

+0

To naprawdę nie wyjaśnia, co się dzieje. Po naprawieniu problemu przekierowania polecenia stają się ctrl-c-interupptible. Jeśli weźmiesz pod uwagę, że większość czasu upłynie, czekam na wygaśnięcie ttl. Tak więc prawdopodobieństwo, że mój Ctrl + C znajdzie się w krótkim momencie wykonania powłoki, jest zerowe. –

3

Coś zwykle zrobić w tego rodzaju pętli jest dodanie komendy sleep zamiast true:

while ! ping 8.8.8.8 -c 1 &> /dev/null ; do sleep 1; done; 

W ten sposób można użyć Ctrl+C podczas gdy w śnie i anulować całą pętlę.

+0

Dzięki, ale, widocznie, 'podczas gdy! ping 8.8.8.8 -c 1 &>/dev/null; czyńcie prawdę; done; 'jest w stanie przerwać, więc nie widzę powodu, aby używać snu. "true" jest także krótsze: p. –

+0

Tak, ale jest mniej agresywny w twojej sieci :). – FJRA

+0

Zobacz mój komentarz na odpowiedź @chepner. Teraz zdaję sobie sprawę z użyteczności funkcji spania. Zwiększa prawdopodobieństwo, że bash działa po kliknięciu Ctrl + C. –

1

Myślę, że lepszym sposobem jest ustawienie limitu czasu w ping.

while ! ping -c 1 -W 2 8.8.8.8 >/dev/null 2>&1 ; do sleep 1 ; done 
Powiązane problemy