由于 ICMP 主机不可达,Linux ping 命令提前退出

由于 ICMP 主机不可达,Linux ping 命令提前退出

一个自动化脚本shutdown -r now在机器上运行,经过 30 秒的延迟后,使用 ping 来确定机器何时可用。我最近将操作系统从 Centos 5 切换到 Oracle Linux 6,发现 ping 的行为发生了变化。

我使用带有计数(-c10)、截止期限(-w360)和延迟(-W1)的 ping,它应该等待最多五分钟才能收到机器的十次成功答复。

我观察到我的机器Destination Host Unreachable在 30 秒后生成消息,导致ping在出现 3 个错误后退出,即远早于我期望的截止时间值。例如,在约 37 秒后退出:

[cs@bst1 ~]# time ping -c10 -w360 -W1 hostother; echo $?
PING hostother (10.210.51.155) 56(84) bytes of data.
From bst1 (10.210.51.139) icmp_seq=36 Destination Host Unreachable
From bst1 (10.210.51.139) icmp_seq=37 Destination Host Unreachable
From bst1 (10.210.51.139) icmp_seq=38 Destination Host Unreachable

--- hostother ping statistics ---
38 packets transmitted, 0 received, +3 errors, 100% packet loss, time 37008ms
pipe 3

real    0m37.010s
user    0m0.001s
sys     0m0.000s
1

这似乎与以下内容相冲突man ping

如果 ping 根本没有收到任何回复数据包,它将以代码 1 退出。如果指定了数据包计数和截止时间,并且到截止时间时收到的数据包少于计数个数,它也将以代码 1 退出。如果发生其他错误,它将以代码 2 退出。否则它将以代码 0 退出。这使得可以使用退出代码来查看主机是否处于活动状态。

1) ping 在遇到 ICMP 错误时的行为是否与手册页一致?似乎在错误情况下返回代码应该是 2。

2) 是否有可能阻止我自己的机器跳出这些Destination Host Unreachable消息?

如果我重新运行 ping 几次,它最终会看到主机并干净退出(返回代码 0)。

答案1

我建议您渗透超时ping并改用timeout命令(coreutils 的一部分):

timeout 300s bash -c "until ping -c10 hostother; do false; done"

你会得到124如果命令超时,则返回代码;例如,如果在 5 分钟内连续 10 次 ping 都无法成功,并且0如果ping成功,立即行动。

我知道这不真的回答问题(我承认ping手册页不是很清楚)但希望能解决您的眼前问题。

答案2

1) 是的,PING 的行为是一致的。“目标主机无法访问”可能意味着很多事情,但其中之一是“该主机的地址表明它位于我的 LAN 上,但它不响应 ARP 请求,而且我没有它的有效 ARP 缓存条目“。

这是我在 LAN 上对某个设备执行 PING 操作,结果显示没有 ARP 缓存条目:

[me@risby]$ ping 192.168.3.244
PING 192.168.3.244 (192.168.3.244) 56(84) bytes of data.
From 192.168.3.11 icmp_seq=1 Destination Host Unreachable
From 192.168.3.11 icmp_seq=2 Destination Host Unreachable
From 192.168.3.11 icmp_seq=3 Destination Host Unreachable
[...]
[me@risby]$ arp -a -n|grep 244
? (192.168.3.244) at <incomplete> on p1p1

PING 没有产生错误 2,因为确实没有收到任何回复数据包。这也不是 PING 的问题;它已要求内核发送 icmp echo 请求,而内核已指示它无法这样做。以下是错误 2 的一个例子,即“我,PING,根本无法执行这些指令;我失职了“:

[me@risby]$ ping -c 3 192.168.3.999
ping: unknown host 192.168.3.999
[me@risby]$ echo $?
2

2)不是。

正如其他人所暗示的,您选择了错误的方式来测试主机是否关闭,而不是使用 ICMP-echo-r​​equest-unresponsive。

相关内容