2015-11-28 6 views
3

Иногда мой DSL маршрутизатор терпит неудачу в этом странным образом:

[email protected]:~$ sudo ping 8.8.8.8 -I eth9 
[sudo] password for luis: 
PING 8.8.8.8 (8.8.8.8) from 192.168.3.100 eth9: 56(84) bytes of data. 
64 bytes from 8.8.8.8: icmp_seq=1 ttl=47 time=69.3 ms 
ping: sendmsg: Operation not permitted 
64 bytes from 8.8.8.8: icmp_seq=3 ttl=47 time=68.0 ms 
ping: sendmsg: Operation not permitted 
64 bytes from 8.8.8.8: icmp_seq=5 ttl=47 time=68.9 ms 
64 bytes from 8.8.8.8: icmp_seq=6 ttl=47 time=67.2 ms 
ping: sendmsg: Operation not permitted 
64 bytes from 8.8.8.8: icmp_seq=8 ttl=47 time=67.2 ms 
^C 
--- 8.8.8.8 ping statistics --- 
8 packets transmitted, 5 received, 37% packet loss, time 7012ms 
rtt min/avg/max/mdev = 67.254/68.183/69.391/0.906 ms 
[email protected]:~$ echo $? 
0 

Как можно видеть, код ошибки $? является 0. Поэтому я не могу просто определить, не сработала ли команда, так как на выходе получается без ошибок для любого скрипта.

Что такое надлежащим образом определить, что произошла потеря пакетов?
Нужно ли разобрать выход с grep или есть какой-нибудь более простой способ?

ответ

2

Согласно man странице по умолчанию (на Linux), если пинг не получает ответные пакеты на всех, она будет завершаться с кодом 1. Но если пакета подсчитывать (-c) и тайм-аут крайнего срока (-w, секунда) оба определены, и меньше пакетов до тайма-аута принимается, он будет также выход с кодом 1. На других ошибках он выходит с кодом 2.

ping 8.8.8.8 -I eth9 -c 3 -w 3 

Таким образом, код ошибки будет установлен, если 3 пакета не принимаются в течение 3 секунд.

В @ mklement0 отметил, ping on BSD ведет себя несколько иным образом:

пинг коммунальные выходы с одним из следующих значений:

- по крайней мере, один ответ был слышен из указанный хост.

- передача прошла успешно, но ответов не получено.

Таким образом, в этом случае следует попытаться обойти его с отправкой по одному в цикле

ip=8.8.8.8 
count=3 
for i in $(seq ${count}); do 
    ping ${ip} -I eth9 -c 1 
    if [ $? -eq 2 ]; then 
     ## break and retransmit exit code 
     exit 2 
    fi 
done 

Конечно, если вам нужна полная статистика, просто рассчитывать коды «2» и «0» к некоторым переменным и выводить код ошибки результата после для, если вам нужно.

+1

Хорошая информация, но обратите внимание, что она специфична для _GNU_ 'ping' (Linux); BSD 'ping', также используемый в OS X, имеет разные варианты и поведение. – mklement0

+1

@ mklement0 хорошая точка, исправлено – pmod