如何通过Ping命令判断成功响应而非TTL过期以获取跳数?
用Ping递增TTL获取网络跳数的正确实现
你的需求是通过循环递增TTL值执行Ping,区分目标主机的成功响应和中间节点的TTL过期提示,但当前代码仅通过ping的返回码判断,这会导致误判——因为当TTL过期时,部分系统(比如Windows)的ping命令返回码仍为0,无法区分两种情况。
修正思路
不要仅依赖返回码,而是解析ping的输出内容:
- 目标主机成功响应时,输出会包含类似
Reply from x.x.x.x(Windows)或64 bytes from x.x.x.x(Linux)的特征字符串 - TTL过期时,输出会包含
TTL expired in transit(Windows)或Time to live exceeded(Linux)的特征字符串
适配Windows环境的修正代码
success=0 counter=1 while [ $success -eq 0 ]; do echo "TTL: $counter" # 执行ping并捕获所有输出 ping_output=$(ping -n 1 google.com -i $counter 2>&1) # 检查是否收到目标主机的有效响应 if echo "$ping_output" | grep -q "Reply from"; then success=1 else # 检查是否是TTL过期,继续递增循环 if echo "$ping_output" | grep -q "TTL expired in transit"; then ((counter++)) else # 处理域名解析失败等未知错误,避免无限循环 echo "Ping出现未知错误,退出循环" exit 1 fi fi done echo "到达目标的跳数为: $counter"
适配Linux环境的修正代码
Linux下ping的TTL参数为-t(-i是包发送间隔),输出特征也不同,代码调整如下:
success=0 counter=1 while [ $success -eq 0 ]; do echo "TTL: $counter" ping_output=$(ping -c 1 google.com -t $counter 2>&1) # 检查是否收到目标主机的有效响应 if echo "$ping_output" | grep -q "bytes from"; then success=1 else # 检查是否是TTL超时,继续递增循环 if echo "$ping_output" | grep -q "Time to live exceeded"; then ((counter++)) else echo "Ping出现未知错误,退出循环" exit 1 fi fi done echo "到达目标的跳数为: $counter"
关键说明
-n 1(Windows)/-c 1(Linux):仅发送1个ICMP包,减少等待时间- 通过
grep匹配输出特征字符串,精准区分目标响应与TTL过期场景 - 增加未知错误分支,避免因域名解析失败等问题导致无限循环
内容的提问来源于stack exchange,提问作者Abdelkader Abdelbaki
相关产品推荐
相关产品推荐

