如何仅显示ping
结果的状态而不是整个输出ping
?
** My server1 is .... online
** My server2 is .... online
** My server3 is .... offline
我尝试了以下方法,但失败了
@echo off ping My server1|find "Reply from " >NUL
IF NOT ERRORLEVEL 1 echo Success
IF ERRORLEVEL 1 echo Fail
ping My server2|find "Reply from " >NUL
IF NOT ERRORLEVEL 1 echo Success
IF ERRORLEVEL 1 echo Fail
ping My server3|find "Reply from " >NUL
IF NOT ERRORLEVEL 1 echo Success
IF ERRORLEVEL 1 echo Fail
echo My server1 is ....%ver%
echo My server2 is ....%ver%
echo My server3 is ....%ver%
如何在这里设置变量来实现这样的效果?
答案1
您不需要使用find
:成功状态由命令本身返回ping
:-
ping -c 1 MyServer1>nul:
set stat=on-line
if errorlevel 1 set stat=off-line
echo MyServer1 is %stat%
您可能希望将这些命令放入ServerCheck.cmd
并使用%1
而不是显式的MyServer1
,以便您可以在循环中调用它(记住如果循环本身在批处理文件中则for
使用)。call ServerCheck.cmd
for
答案2
@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%