批量命令捕获所有可能的ping问题

我有一个关于validationping是否在批处理命令中正确返回的问题。 目前我必须检查ping 3种不同的方法来知道服务器实际上是up的。 我想把它们合并成一个单一的ping命令。 我已经尝试使用不同的错误级别或不errorlevel 0等,他们都没有抓住所有可能的情况。 这是我一直在使用的:

Set /p domain=Enter IP address: set state=up @ping.exe -n 1 %domain% | find "unreachable" > null && set state=down if "%state%" == "down" goto :NoServer @ping.exe -n 1 %domain% | find "TTL expired" > null && set state=down if "%state%" == "down" goto :NoServer @ping.exe -n 1 %domain% if errorlevel 1 goto :NoServer 

有两种方法可以检查ping命令的成功或失败:在执行后testing错误级别或testing命令的输出。 对于这两种情况,检查ipv4或ipv6地址是不一样的。

问题是: ping如何performance?它的输出是什么? 什么时候设置错误errorlevel

错误errorlevel

如果我们正在使用ipv6,规则是

  • 当所有发送的数据包都没有应答时,设置errorlevel (所有数据包丢失)

  • 如果有任何发送的数据包的回复, errorlevel不会被设置

ipv6具有一致的行为,并检查errorlevel是一种可靠的方式来知道机器是否在线。

在ipv4中,规则是不同的

  • 如果至less有一个发送的数据包没有回复,则设置errorlevel

  • 当所有发送的数据包都有回复时,没有设置错误errorlevel (没有数据包丢失)

但是,在ipv4中,在同一个子网上ping一台不可用的机器不会设置错误errorlevel ,您将得到一个“不可达”的答案, n packets sent, n packed received, 0 packets lost ,所有数据包都得到相同的答复机器发送数据包。

当机器在同一子网中时,在ipv4中的这种行为使错误级别检查失败。

如何解决ipv4中的问题? 输出检查

可以检查ping命令的输出,如果输出中存在stringTTL= ,目标机器在线。

 ping -n 1 10.0.0.1 | find "TTL=" >nul if errorlevel 1 ( echo offline ) else ( echo online ) 

但是在ipv4中工作的这种方法将会失败,并且ipv6将会失败,因为这个字段没有被包含在ping输出中(并且在ipv6中被重命名为跳跃限制


对于“通用”解决scheme,可以使用(从以前的答案改编)(似乎很多代码,但几乎都是注释)。 ping操作和输出处理被封装在一个子程序中,该子程序通过作为batch file的第一个parameter passing的地址/主机名来调用。

 @echo off setlocal enableextensions disabledelayedexpansion if "%~1"=="" goto :eof call :isOnline "%~1" if not errorlevel 1 ( echo ONLINE ) else ( echo OFFLINE ) endlocal exit /b :isOnline address pingCount setlocal enableextensions disabledelayedexpansion :: send only one ping packed unless it is indicated to send more than one set /a "pingCount=0", "pingCount+=%~2" >nul 2>nul if %pingCount% lss 1 set "pingCount=1" :: a temporary file is needed to capture ping output for later processing set "tempFile=%temp%\%~nx0.%random%.tmp" :: ping the indicated address getting command output and errorlevel ping -w 1000 -n %pingCount% "%~1" > "%tempFile%" && set "pingError=" || set "pingError=1" :: :: When pinging, the behaviours of ipv4 and ipv6 are different :: :: we get errorlevel = 1 when :: ipv4 - when at least one packet is lost. When sending more than one packet :: the easiest way to check for reply is search the string "TTL=" in :: the output of the command. :: ipv6 - when all packet are lost. :: :: we get errorlevel = 0 when :: ipv4 - all packets are received. BUT pinging a inactive host on the same :: subnet result in no packet lost. It is necessary to check for "TTL=" :: string in the output of the ping command :: ipv6 - at least one packet reaches the host :: :: We can try to determine if the input address (or host name) will result in :: ipv4 or ipv6 pinging, but it is easier to check the result of the command :: :: +--------------+-------------+ :: | TTL= present | No TTL | :: +-----------------------+--------------+-------------+ :: | ipv4 errorlevel 0 | OK | ERROR | :: | errorlevel 1 | OK | ERROR | :: +-----------------------+--------------+-------------+ :: | ipv6 errorlevel 0 | | OK | :: | errorlevel 1 | | ERROR | :: +-----------------------+----------------------------+ :: :: So, if TTL= is present in output, host is online. If TTL= is not present, :: errorlevel is 0 and the address is ipv6 then host is online. In the rest :: of the cases host is offline. :: :: To determine the ip version, a regular expresion to match a ipv6 address is :: used with findstr. As it will be only tested in the case of no errorlevel, :: the ip address will be present in ping command output. set "exitCode=1" >nul 2>nul ( find "TTL=" "%tempFile%" && ( set "exitCode=0" ) || ( if not defined pingError ( findstr /r /c:" [a-f0-9:][a-f0-9]*:[a-f0-9:%%]*[a-f0-9]: " "%tempFile%" && set "exitCode=0" ) ) del /q "%tempFile%" ) :: cleanup and return errorlevel: 0=online , 1=offline endlocal & exit /b %exitCode% 
 ping.exe -n 1 %domain% >tempfile if not errorlevel 1 ( findstr /i /c"unreachable" /c:"TTL expired" > null if errorlevel 1 goto :OK ) :Noserver 

应该使用一个ping来复制你的testing。 我不确定ping是否返回所有错误条件的非零值,或者可能是您的目标string和错误级别0之一。您需要指定。