我正在尝试找到一种方法,以基于一系列4次ping的结果,使批处理文件做出不同的响应。如果ping丢失0%,则应打开一个网页。如果该命令返回的损失%大于0,则应启动goto命令。
我已经尝试过的事情是将代码中的“其他”更改为“%errorlevel%” ==“ 4”还是“%errorlevel%” ==“ 100”
:login3
cls
echo.
echo Login information cleared!
echo Press any key to confirm internet connection.
pause > nul
ping 8.8.8.8
if "%errorlevel%"=="0" start "" https://stackoverflow.com
else goto :login_fail
cls
echo.
echo test
echo if you got connected to the website, then you should end up here.
pause
exit
:login_fail
cls
color 0c
echo.
echo Login failed. Try again later.
pause > nul
无论我是否可以连接互联网,我都会始终收到测试邮件,并且网站将尝试打开。
答案 0 :(得分:1)
ping
的错误级别没有用。 (很可惜)什么都没告诉你。
您可以提取“亏损百分比”(也没有用,正如@Mofi指出的那样),也可以自己动手:计算成功回报的发生率(并根据需要做一些数学运算):
@echo off
setlocal
set "addr=8.8.8.8"
set tries=4
for /f %%a in ('ping %addr% /n %tries% ^|find /c "TTL="') do set "ret=%%a"
if %ret%==%tries% (goto :open_url) else (goto :login_fail)
REM some math to get the percentages, should anyone have use for it:
echo Returns/Tries = %ret%/%tries%
set /a succ=ret*100/tries
set /a loss=100-ret*100/tries
echo loss=%loss%; success=%succ%
goto :eof
:open_url
REM insert code
goto :eof
:login_fail
REM insert code
goto :eof
答案 1 :(得分:0)
Find
将满足您的需求。( ( PING 8.8.8.8 | FIND /I "Reply From 8.8.8.8" >Nul ) && ECHO(Success! ) || ECHO(Failure!
以下是使用此方法的原始代码:
:login3
cls
echo.
echo Login information cleared!
echo Press any key to confirm internet connection.
pause > nul
(
PING 8.8.8.8 | FIND /I "Reply From 8.8.8.8" >Nul && (
start "" https://stackoverflow.com
cls
echo.
echo test
echo if you got connected to the website, then you should end up here.
pause
)
) || (
cls
color 0c
echo.
echo Login failed. Try again later.
pause > nul
)
Exit /b
&&允许您测试成功,而||测试失败,并且由于Find只会报告成功或失败一次,因此我们不必担心我们要测试多少次(尽管您可能有理由测试4次以上或少于4次ping,我们将对此进行处理现在)
这意味着,如果我们匹配该回复并且它具有我们想要的原始IP,那么我们知道它一定是来自我们正在ping的主机的回复,我们将获得成功,并在&&中执行所有操作
但是,如果我们从不匹配预期结果,则Find将返回失败,并且我们将跳过&&块并执行||中的所有内容。
啊,这总是需要做的事情,要知道这些警告很容易。
一开始,您会认为要匹配%Loss One并正确完成?
例如:
REM For /F Example
FOR /F "Tokens=2 Delims=(%%" %A in ('ping 8.8.8.8') DO @( IF /I %%~A GTR 0 ( ECHO. OKAY! ) ELSE ( ECHO.Failed! ) )
REM Find Example
( ( ping 8.8.8.8 | FIND /I "(100%" >nul ) && Echo.Failed! ) || Echo.Success!
好吧,当您的目的地无法由您和IP之间的路由器到达时,路由器有时会回复“ Destination Host Unreachable
”(每次 ,则每X次执行一次ping,或者永远不执行一次,取决于路由器的配置方式。)
这是实际的ICMP回复,因此Ping内部只是跟踪实际的响应并显示其结果,因此损失百分比不会是100%。 无法访问目标主机将被视为答复,因为路由器正在答复您。
Reply from 10.41.3.232: Destination net unreachable.
这意味着您还不能简单地通过For /F
循环或Find
/ FindStr
来计数“ Reply”的匹配项。
但是,正如您从上面的示例中可能已经注意到的那样,在这种情况下会返回路由器的Ip,因此,您希望计数的唯一“答复”始终将包含源IP。
因此,对于您这样的简单支票,以下Find
将满足您的需求。
( ( PING 8.8.8.8 | FIND /I "Reply From 8.8.8.8" >Nul ) && ECHO(Success! ) || ECHO(Failure!
如果愿意,可以调用函数或在&&和||内查找代码。栏目
此外,如何处理使用主机名/ FQDN而不是IP进行ping操作的情况?
在这里,您将要使用For循环从Ping命令获取IP响应,然后将其用于进一步的测试中。
如果启用了“延迟扩展”,则可以在线完成;否则,则需要在函数中进行某些解析。但是,如果您希望收到一个以上的回复(取决于收到的回复数),这也会导致该怎么办。
当您遍历结果时,您将不希望有一个以上的成功案例,因此,最简单的方法是计算无论如何匹配的答复数,然后检查是否大于0,这是微不足道的差异
检查要检查的地址何时是名称而不是IP
@(
SetLocal EnableDelayedExpansion
ECHO OFF
SET "_Count=0"
)
FOR /F "Tokens=1-2 Delims=[]" %%A IN ('Ping www.aol.com') DO (
IF /I "%%B" NEQ "" (
SET "_IP=%%B"
) ELSE (
ECHO.%%A | FIND /I "Reply From !_IP!" >nul && SET /A "_Count+=1"
)
)
IF /I %_Count% GTR 0 (
Echo.Success!
) ELSE (
Echo.Failure!
)
如果您要根据返回的回复数执行不同的操作,则可以使您拥有不止是成功/失败状态。如上文所述,不打扰计数,仅成功或失败几乎是相同的。
但是,仅当初始项不是IP时,它才能如上所述工作。
对IP进行上述操作与原始情况基本相同,但在此要彻底说明的是:
检查何时提供IP并保持计数
@(
SetLocal EnableDelayedExpansion
ECHO OFF
SET "_Count=0"
)
FOR /F "Tokens=*" %A IN ('PING 8.8.8.8 ^| FIND /I "Reply From 8.8.8.8"') DO (
SET /A "_Count+=1"
)
IF /I %_Count% GTR 0 (
Echo.Success!
) ELSE (
Echo.Failure!
)
但这仅在它是IP时有效。
但是,好的,您现在可能想知道如何处理这两者,我觉得我真的应该在某种程度上解决这个问题。
因此,如果您执行两次ping操作,则可以检查Ping是否通过DNS解析了该名称,但是,在任何给定的DNS查询中,您都有可能获得不同的IP地址。
通过在测试中使用Ping -a
,可以强制所有可解析的IP 显示括号,然后可以使用bulkier命令。
C:\Admin>ping -a 8.8.8.8
Pinging dns.google [8.8.8.8] with 32 bytes of data:
但是,这不考虑没有反向指针但仍可ping通的IP。
C:\Admin>ping -a 10.10.172.1
Pinging 10.10.172.1 with 32 bytes of data:
因此,如果您执行两次ping操作,则可以检查Ping是否通过DNS解析了该名称,但是,在任何给定的DNS查询中,您都有可能获得不同的IP地址,因此尽管我们有两个循环,并设置说1 ping只是为了查看它是否能够解决,我们不能使用结果并放弃第二个循环,即使将ping设置为1响应,我们也会使过程更长。
因此,最好不要对ping命令进行不必要的调用,尤其是在某些情况下响应时间较长时。
要做到这一点,我们应该稍微改变设置_IP
变量的方式,只用一个循环和一个ping命令即可完成我们的两个目标。
为此,我们更改了逻辑以查看是否定义了_IP
变量,如果没有定义,我们将检查第二项是否找到了某些内容( IE中包含IP的大括号。在这种情况下,我们可以使用该IP,如果该术语为空,我们将假定最初给定的地址是IP,而不是名称。
注意:如果是名称,但DNS无法解析,则无论如何我们都无法ping通,并且Ping只会为此抛出一条错误消息,然后退出,因此我们不这样做需要担心该值是名称而不是IP。
在这种情况下,测试是否已定义我们的变量_IP
。
@(
SetLocal EnableDelayedExpansion
ECHO OFF
SET "_PingAddress=www.aol.com"
SET "_Count=0"
)
FOR /F "Tokens=1-2 Delims=[]" %%A IN ('Ping %_PingAddress%') DO (
IF NOT DEFINED _IP (
IF /I "%%B" NEQ "" (
SET "_IP=%%B"
) ELSE (
SET "_IP=%_PingAddress%"
)
) ELSE (
ECHO.%%A | FIND /I "Reply From !_IP!" >nul && SET /A "_Count+=1"
)
)
IF /I %_Count% GTR 0 (
Echo.Success!
) ELSE (
Echo.Failure!
)
这也比对Address IMO的原始测试要干净一些,并且可以处理这种IP情况。