我有一个相当简单的小脚本。基本上,它在给定域上执行 ping。是这样的:
ping -c2 $1 | head -n4
它打印出例如:
PING google.com (172.217.17.206): 56 data bytes
64 bytes from 172.217.17.206: icmp_seq=0 ttl=55 time=2.474 ms
64 bytes from 172.217.17.206: icmp_seq=1 ttl=55 time=2.668 ms
这对我来说没问题。
但例如,正如您所知,有时 ping 命令不会从 ICMP 请求返回任何响应。例如:
ping intel.com
PING intel.com (13.91.95.74): 56 data bytes
Request timeout for icmp_seq 0
Request timeout for icmp_seq 1
--- intel.com ping statistics ---
当这种情况发生时,脚本会卡住几秒钟,然后继续前进。当这种情况发生时,我试图想办法跳过它并继续下去。我实际上不确定这是否可能。我一开始想将它通过管道传递给 grep 来表示“请求超时”,或者将结果放入变量中,然后 cat | grep 变量。
有人可以想出一种方法吗?当请求超时时是否可以跳过执行?
答案1
如果您不希望在服务器无法响应时卡住“几秒钟”,请使用该-W
选项添加超时。例如:
ping -c2 -W2 "$1"
-W2
设置两秒时间。更改限制以满足您的需求。
在旁边
当引用 shell 变量时,例如$1
,总是将它们放在双引号中,例如"$1"
,除非您明确知道并且想要分词和路径名扩展。
文档
从man ping
:
-W timeout
等待响应的时间,以秒为单位。该选项仅影响没有任何响应的超时,否则 ping 会等待两个 RTT。
答案2
@John1024 的答案对于 Linux 发行版来说是正确的。由于您的问题不是特定于操作系统的,因此我将提供一个 BSD 解决方案。
BSD 的ping
命令(也包括 Mac OS X)在某些计时参数上具有更细粒度。大多数网络连接的往返时间远低于一秒。事实上,许多连接的 RTT 小于一毫秒。 FreeBSD 的手册页ping
指定该-W
选项接受以毫秒为单位的参数:
-W等待时间
每个发送的数据包等待回复的时间(以毫秒为单位)。如果稍后收到回复,则不会将数据包打印为已回复,而是在计算统计时将其视为已回复。
使用 FreeBSD 的等效命令ping
是:
ping -c2 -W2000 "$1"
FreeBSD 参数的更高分辨率-W
允许提供一个-W
更接近预期实际 RTT 的值。
假设已知主机testhost
名义上往返时间为 75 毫秒。值为-W
80 将产生:
jimsdesk : 14:45:58 /root# ping -W80 -c2 testhost
PING testhost (10.111.33.21): 56 data bytes
64 bytes from 10.111.33.21: icmp_seq=0 ttl=240 time=74.385 ms
64 bytes from 10.111.33.21: icmp_seq=1 ttl=240 time=74.478 ms
--- testhost ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 74.385/74.431/74.478/0.046 ms
较小的-W
值 50 会产生:
# ping -W50 -c2 testhost
PING testhost (10.111.33.21): 56 data bytes
--- testhost ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss, 2 packets out of wait time
round-trip min/avg/max/stddev = 74.466/74.538/74.611/0.073 ms
假设另一台主机testhost2
距离更近,通常不到 4 毫秒。我们将指定更严格的 -W 容差,即 4 毫秒。我们还可以增加-c
对更多数据包行程时间的采样:
# ping -c10 -W4 testhost2
PING testhost2 (10.216.177.146): 56 data bytes
64 bytes from 10.216.177.146: icmp_seq=0 ttl=59 time=3.730 ms
64 bytes from 10.216.177.146: icmp_seq=1 ttl=59 time=3.899 ms
64 bytes from 10.216.177.146: icmp_seq=2 ttl=59 time=3.949 ms
64 bytes from 10.216.177.146: icmp_seq=3 ttl=59 time=3.668 ms
64 bytes from 10.216.177.146: icmp_seq=4 ttl=59 time=3.881 ms
64 bytes from 10.216.177.146: icmp_seq=5 ttl=59 time=3.725 ms
64 bytes from 10.216.177.146: icmp_seq=6 ttl=59 time=3.826 ms
64 bytes from 10.216.177.146: icmp_seq=8 ttl=59 time=3.726 ms
64 bytes from 10.216.177.146: icmp_seq=9 ttl=59 time=3.728 ms
--- testhost2 ping statistics ---
10 packets transmitted, 10 packets received, 0.0% packet loss, 1 packets out of wait time
round-trip min/avg/max/stddev = 3.668/3.867/4.539/0.241 ms
上面的输出显示,十个数据包中有九个在 4 毫秒或更短的时间内完成了往返,但有一个(seq 7)没有。
进一步降低,许多 LAN RTT 都低于一毫秒,但并非总是如此。ping -c100 -W1 10.10.1.1
在本地网络上运行产生:
...
--- 10.10.1.1 ping statistics ---
100 packets transmitted, 100 packets received, 0.0% packet loss, 10 packets out of wait time
round-trip min/avg/max/stddev = 0.664/1.081/18.547/1.898 ms
100 个数据包中有 90 个在不到一毫秒的时间内返回,但另外 10 个数据包没有返回。
在大多数计算机上,本地主机接口的往返时间为亚毫秒级。不幸的是,FreeBSDping
不接受十进制值-W
:
# ping -c3 -W1 localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.020 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.018 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.020 ms
--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.018/0.019/0.020/0.001 ms
# ping -c3 -W.999 localhost
PING localhost (127.0.0.1): 56 data bytes
--- localhost ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss, 3 packets out of wait time
round-trip min/avg/max/stddev = 0.020/0.022/0.025/0.002 ms
看起来-W
的值.999
被解析为0
。