ping shell脚本:有些数据包丢失,但错误代码$?等于零。我该怎么检测?

时间:2015-11-28 23:57:12

标签: shell ping packet-loss

有时我的DSL路由器以这种奇怪的方式失败:

luis@balanceador:~$ 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
luis@balanceador:~$ echo $?
0

可以看出,错误代码$?0。所以我不能简单地检测命令是否失败,因为任何脚本的输出都会产生无错误

检测的正确方法是什么?丢包? 我是否需要使用grep 解析输出,或者有一些更简单的方法?

1 个答案:

答案 0 :(得分:3)

根据man页面,默认情况下(在Linux上),如果ping根本没有收到任何回复数据包,它将以代码1退出。但是如果数据包计数 (-c)和截止时间超时(-w,秒)都被指定,并且收到超时之前的数据包越少,它也将以代码1退出。在其他错误上,它以代码2退出。

ping 8.8.8.8 -I eth9 -c 3 -w 3

因此,如果在3秒内没有收到3个数据包,将设置错误代码。

正如@ mklement0所指出的那样,ping on BSD表现得有点不同:

  

ping实用程序以下列值之一退出:

     

0 - 从指定的主机听到至少一个回复。

     

2 - 传输成功但未收到回复。

因此,在这种情况下,应该尝试在循环中逐个发送

来解决它
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"如果需要,可以在 for 循环后的某些变量和打印结果/设置错误代码。