使用 Bat 文件进行 Ping 测试 - 错误级别出现问题

问题描述 投票:0回答:5

我正在使用批处理文件设置 LAN ping 测试。 我的代码对于网站来说效果很好,但对于本地 IP 来说却很奇怪。 我正在 3 台我知道 IP 的计算机上运行 ping 测试。 无论我拔掉哪一台,当我运行下面的代码时,所有三台计算机上的 %errorlevel% 始终为 0。 它永远不会像网站上那样等于 1。 我该如何解决这个问题?

@echo off
cls
Set IPaddress=www.google.com
PING %IPaddress% -n 1
 call :PingTest

Set IPaddress=www.yahoo.com
PING %IPaddress% -n 1
 call :PingTest

Set IPaddress=www.unabletoping.com
PING %IPaddress% -n 1
 call :PingTest

pause > null
exit

:PingTest
IF %errorlevel% EQU 1 (echo "Server is Offline") else (GOTO:EOF)
batch-file ping
5个回答
20
投票

当您 ping 子网中不可访问的地址时,您会得到“无法访问”的答案,其中发送了 1 个数据包,接收了 1 个数据包,丢失了 0 个数据包。错误级别未设置。

当您 ping 子网之外的不可访问地址时,您会得到“超时”答案,发送 1 个数据包,接收 0 个数据包,丢失 1 个数据包。错误级别已设置。

并且,您可以 ping 活动机器、丢失数据包并获取错误级别

并且,您可以 ping 活动/非活动机器,获取 TTL 过期并且没有错误级别

更好,检查 ping 响应的内容。

ping -n 1 192.168.1.1 | find "TTL=" >nul
if errorlevel 1 (
    echo host not reachable
) else (
    echo host reachable
)

1
投票

虽然我无法复制您的问题,但我确实对您的脚本有一些建议。 (有关该问题的问题请参阅我的评论)

  1. 创建变量时封装范围。
    setlocal
    endlocal
  2. 退出脚本时,使用 /b 标志以免终止调用者的命令提示符。
  3. nul 不为空。

示例():

@echo off
setlocal
cls

set "IPaddress=www.google.com"
call :PingVerbose "%IPaddress%"
call :PingVerbose "www.yahoo.com"
call :PingVerbose "www.microsoft.com"

pause>nul
endlocal
exit /b 0

:Ping <Address>
ping "%~1" -n 1 >nul
exit /b %ErrorLevel%

:PingVerbose <Address>
call :Ping %1 && echo %~1 is Online || echo %~1 is Offline
exit /b %ErrorLevel%

1
投票

虽然我也无法复制您的问题,但也有改进您的脚本的建议 -

@echo off & cls

set addresses=10.1.1.666 10.124.412.14 10.7.254.1

for %%a in (%addresses%) do ping %%a -n 1 > nul || echo %%a is offline

请注意,

||
之后的命令仅在 ping 设置错误级别时才会执行。


0
投票

根据其他人提到的内容,我想展示如何需要执行上面显示的所有操作以及使用修改的变量,例如循环中的计数器。

注意:使用“setlocalenabledelayedexpansion”允许在循环等中使用修改后的变量..

@echo off
setlocal enabledelayedexpansion

REM List of systems to check
set list=www.google.com www.yahoo.com www.notasite.com

set /a failed=0
set /a passed=0
set /a count=0

echo PingTest Servers on %list% :

(for %%a in (%list%) do ( 
    set /a "count+=1"
    call :PingVerbose %%a && set /a "passed=!passed!+1" || set /a "failed=!failed!+1"
))

echo ------------
echo Result: %passed% of %count% systems are pingable
pause
endlocal
exit /b 0

:Ping <Address>
ping "%~1" -n 1 >NUL
exit /b %ErrorLevel%

:PingVerbose <Address>
call :Ping %1 && echo %~1 - [ONLINE] || echo %~1 - [OFFLINE] 
exit /b %ErrorLevel%

输出:

PingTest Servers on www.google.com www.yahoo.com www.notasite.com :
www.google.com - [ONLINE]
www.yahoo.com - [ONLINE]
www.notasite.com - [OFFLINE]
------------
Result: 2 of 3 systems are pingable
Press any key to continue . . .         

0
投票

测试

ERRORLEVEL
设置的
ping
是徒劳的,因为在某些情况下,即使没有从远程主机收到任何有效回复,它也会将
ERRORLEVEL
设置为 0(成功)!!!

但是,下面描述的方法是可靠的、可移植的并且适用于:

  1. 翻译成所有其他语言,例如:“ms”、“TTL”、“回复”、“丢失”、“无法到达”、“已收到”等...,包括俄语和中文。
  2. Ping IPv4 地址。
  3. Ping IPv6 地址(无
    TTL
    字段)
  4. 发生错误“一般故障”的情况。
  5. Ping 一个地址,返回 “请求超时。”
  6. Ping 一个地址,返回 “目标主机无法访问。”
  7. Ping 可解析的字母数字主机。
  8. Ping 无法解析的字母数字主机,这会导致返回 “Ping 请求无法找到主机 UnresolvableHost...” 错误。
@echo off

for /F %%A in ('ping %1 -n 1 ^| findstr /C:^= ^| find /c /v ""') do (set "res=%%A")

if %res% GEQ 3 (
    echo SUCCESS.
) else (
    echo FAILURE.
)

如果将上面的代码保存到名为例如

pingtest.bat
,你可以这样使用它:

pingtest 192.168.1.1

此方法利用了字符串中存在的等号

bytes=
,这些等号不受翻译为其他语言的影响,并且不会出现在不成功的 ping/echo 结果中。

此外,将开关

-n 1
修改为例如
-n 6
允许您在变量
%res%
中获得反映连接质量的定性结果。

使用下面的代码,您可以标准化变量

%res%
中的结果,使其在失败时变为
0
...以及在成功时 - 成功 ping 的数量:

@echo off

for /F %%A in ('ping %1 -n 6 ^| findstr /C:^= ^| find /c /v ""') do (set "res=%%A")

if %res% GEQ 3 (
    set /A "res=%res%-2"
) else (
    set "res=0"
)

echo The number of successful pings is %res%

要暂停程序直到成功 ping 通主机,只需像这样循环调用它:

@echo off

:loop
for /F %%A in ('ping %1 -n 1 ^| findstr /C:^= ^| find /c /v ""') do (set "res=%%A")

if %res% LSS 3 goto :loop
© www.soinside.com 2019 - 2024. All rights reserved.