Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Batch file 如何使批处理文件根据ping命令的成功率做出不同的反应?_Batch File - Fatal编程技术网

Batch file 如何使批处理文件根据ping命令的成功率做出不同的反应?

Batch file 如何使批处理文件根据ping命令的成功率做出不同的反应?,batch-file,Batch File,我正试图找到一种方法,使批处理文件根据一系列4次ping的结果做出不同的响应。如果ping丢失率为0%,则应打开一个网页。如果命令返回的损失百分比高于0,则应启动goto命令 我已经尝试过的事情是将代码中的“else”更改为如果“%errorlevel%”==“4”或如果“%errorlevel%”==“100” 如果我有或没有internet连接,我将始终被发送到测试消息,网站将尝试打开。ping的错误级别是无用的。它(遗憾地)没有告诉你任何事情 您可以提取“损失百分比”(正如@Mofi已经指

我正试图找到一种方法,使批处理文件根据一系列4次ping的结果做出不同的响应。如果ping丢失率为0%,则应打开一个网页。如果命令返回的损失百分比高于0,则应启动goto命令

我已经尝试过的事情是将代码中的“else”更改为如果“%errorlevel%”==“4”或如果“%errorlevel%”==“100”


如果我有或没有internet连接,我将始终被发送到测试消息,网站将尝试打开。

ping的错误级别是无用的。它(遗憾地)没有告诉你任何事情

您可以提取“损失百分比”(正如@Mofi已经指出的,这也是无用的),也可以自己做:计算成功回报的发生率(如果需要,做一些数学计算):

对于像您这样的简单检查,以下
Find
将满足您的需要。 这是使用此方法的原始代码:

: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将返回失败,我们将跳过&&块并执行| |块中的所有内容

现在,为了深入了解问题的实质,我们为什么不使用%损失或错误级别: 啊,这类事情总是被认为是需要做的,而且很容易处理,你知道这些注意事项

从一开始,你会认为是匹配%的损失一,做得对吗

例如:

当您与IP之间的路由器无法到达某个目的地时,路由器有时会以“
目的地主机无法到达
”进行回复(这可能发生在每一次ping、每X次ping中一次,或者永远不会发生,取决于路由器的配置方式

这是一个实际的ICMP回复,因此内部Ping只是跟踪实际响应,并显示其结果,因此%的损失不会是100%。 无法访问的目标主机将被视为答复,因为路由器正在答复您

Reply from 10.41.3.232: Destination net unreachable.
这意味着您也不能简单地通过
For/F
循环或
Find
/
FindStr
计算“Reply”的匹配项

( ( PING 8.8.8.8 | FIND /I "Reply From 8.8.8.8" >Nul ) && ECHO(Success! ) || ECHO(Failure!
@(
  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!
)
但是,正如您从上面的示例中注意到的,在这些情况下,路由器的Ip是返回的,因此您希望计数的唯一回复总是包含源Ip

因此,对于像您这样的简单检查,以下
Find
将满足您的需要。

( ( PING 8.8.8.8 | FIND /I "Reply From 8.8.8.8" >Nul ) && ECHO(Success! ) || ECHO(Failure!
@(
  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!
)
如果您愿意,您可以调用函数或在&&和| |部分中生成代码

此外,如何处理使用主机名/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时,它才能如上所述工作。

( ( PING 8.8.8.8 | FIND /I "Reply From 8.8.8.8" >Nul ) && ECHO(Success! ) || ECHO(Failure!
@(
  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!
)
对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命令进行不必要的调用,特别是因为某些场景需要很长时间才能响应

要做到这一点,我们应该稍微改变设置
\u IP
变量的方法,只需一个循环和一个ping命令即可实现这两个目标

为此,我们更改逻辑以查看是否定义了
\u IP
变量,如果没有定义,则检查第二个术语是否发现了什么(即括号中的IP