如何在批处理文件中检查ping是否响应

时间:2010-06-16 05:27:21

标签: command-line batch-file ping

我想连续ping服务器并在响应时看到一个消息框,即服务器当前已关闭。我想通过批处理文件来完成。

我可以在此处显示一个消息框Show a popup/message box from a Windows batch file

可以通过

连续ping
ping <servername> -t

但我该如何检查是否有回应?

11 个答案:

答案 0 :(得分:28)

问题是看ping是否响应了这个脚本的作用。

但是,如果您收到Host Unreachable消息,则此操作无效,因为这会返回ERRORLEVEL 0并传递此脚本中使用的Received = 1的检查,并返回脚本中的Link is UP。当ping被传递到目标notwork但无法找到远程主机时,会发生Host Unreachable。

如果我记得检查ping是否成功的正确方法是使用Find查找字符串'TTL'。

@echo off
cls
set ip=%1
ping -n 1 %ip% | find "TTL"
if not errorlevel 1 set error=win
if errorlevel 1 set error=fail
cls
echo Result: %error%

这不适用于IPv6网络,因为在接收来自IPv6地址的回复时ping不会列出TTL。

答案 1 :(得分:19)

以下checklink.cmd计划是一个很好的起点。它依赖于你可以进行单次ping的事实,如果成功,输出将包含该行:

Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),

通过提取代币5和7并分别检查它们"Received""1,",您可以检测到成功。

@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
:loop
set state=down
for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
    if "x%%b"=="xunreachable." goto :endloop
    if "x%%a"=="xReceived" if "x%%c"=="x1,"  set state=up
)
:endloop
echo.Link is !state!
ping -n 6 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal

使用您要测试的名称(或IP地址)调用它:

checklink 127.0.0.1
checklink localhost
checklink nosuchaddress

请注意,如果您的语言区域不是英语,则必须将Received替换为您语言环境中的相应关键字,例如recibidos替换为西班牙语。执行测试ping以发现您的语言环境中使用的关键字。


要仅在状态更改时通知您,您可以使用:

@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=down
for /f "tokens=5,7" %%a in ('ping -n 1 !ipaddr!') do (
    if "x%%a"=="xReceived" if "x%%b"=="x1," set state=up
)
if not !state!==!oldstate! (
    echo.Link is !state!
    set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal

但是,正如Gabe在评论中指出的那样,您可以使用ERRORLEVEL,因此上面第二个脚本的等效内容变为:

@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
set oldstate=neither
:loop
set state=up
ping -n 1 !ipaddr! >nul: 2>nul:
if not !errorlevel!==0 set state=down
if not !state!==!oldstate! (
    echo.Link is !state!
    set oldstate=!state!
)
ping -n 2 127.0.0.1 >nul: 2>nul:
goto :loop
endlocal

答案 2 :(得分:5)

我知道这是一个旧线程,但我想测试一台机器是否在我的系统上,除非我误解了,如果我的路由器报告地址无法访问,则上述任何一个都无效。我使用批处理文件而不是脚本,因为我想&#34; KISS&#34;在几乎任何WIN机器上。所以我使用的方法是做多个ping并测试&#34; Lost = 0&#34;如下

ping -n 2 %pingAddr% | find /I "Lost = 0"  
if %errorlevel% == 0 goto OK

我还没有经过严格的测试,但到目前为止,它确实为我做了工作

答案 3 :(得分:1)

我根据paxdiablo的帖子

制作了变体解决方案

将以下代码放在Waitlink.cmd

@setlocal enableextensions enabledelayedexpansion
@echo off
set ipaddr=%1
:loop
set state=up
ping -n 1 !ipaddr! >nul: 2>nul:
if not !errorlevel!==0 set state=down
echo.Link is !state!
if "!state!"=="up" (
  goto :endloop
)
ping -n 6 127.0.0.1 >nul: 2>nul:
goto :loop
:endloop
endlocal

例如,从另一个批处理文件中使用它,如

call Waitlink someurl.com
net use o: \\someurl.com\myshare

只有在ping成功时才会返回对waitlink的调用。感谢paxdiablo和Gabe。希望这有助于其他人。

答案 4 :(得分:0)

您可以ping不使用“-t”并检查ping的退出代码。它会在没有答案时报告失败。

答案 5 :(得分:0)

简单版本:

for /F "delims==, tokens=4" %a IN ('ping -n 2 127.0.0.1 ^| findstr /R "^Packets: Sent =.$"') DO (

if %a EQU 2 (
echo Success
) ELSE (
echo FAIL
)

)

但有时候第一次ping失败而第二次失败(反之亦然)对吗?因此,当成功返回至少一个ICMP回复时,我们希望获得成功:

for /F "delims==, tokens=4" %a IN ('ping -n 2 192.168.1.1 ^| findstr /R "^Packets: Sent =.$"') DO (

if %a EQU 2 (
echo Success
) ELSE (
if %a EQU 1 (
echo Success
) ELSE (
echo FAIL
)
)

)

答案 6 :(得分:0)

这是我找到的东西:

:pingtheserver
ping %input% | find "Reply" > nul
if not errorlevel 1 (
    echo server is online, up and running.
) else (
    echo host has been taken down wait 3 seconds to refresh
    ping 1.1.1.1 -n 1 -w 3000 >NUL
    goto :pingtheserver
) 

请注意,ping 1.1.1.1 -n -w 1000 >NUL将等待1秒,但仅在连接到网络时才有效

答案 7 :(得分:0)

我希望这有助于某人。在检查各个路径之前,我使用这一点逻辑来验证网络共享是否响应。它应该处理DNS名称和IP地址

文本文件中的有效路径是 \ 192.168.1.2 \&#39;夹&#39;或\ NAS \&#39;文件夹&#39;

int

答案 8 :(得分:0)

我稍微修改了 PaxDiablo 的代码,以更好地适应我正在做的事情,并认为我会分享。我的目标是遍历 IP 地址列表以查看是否有任何剩余,并且此代码将在周末的最后一个班次结束时运行,以检查是否每个人都按照说明关闭所有 PC 之前他们回家了。

由于在 for 循环中使用 goto 会跳出所有 for 循环,而不仅仅是最底层的嵌套 for 循环,PaxDiablo 的代码在到达无法访问的 IP 地址时停止处理更多 IP 地址。我发现我可以添加第二个变量来跟踪它是不可达的,而不是退出循环,现在这段代码对我来说运行得很好。

我将文件保存为 CheckPCs.bat,虽然我猜这不是正确的编码实践,但我确实在代码下方列出了 IP 地址以及描述,在我的情况下是 PC 的物理位置。正如其他人提到的,您将不得不为其他本地化和 IPV6 进一步修改代码。

@setlocal enableextensions enabledelayedexpansion
@echo off
for /f "tokens=2,3 delims=/ skip=16" %%i in (CheckPCs.bat) do (
set ipaddr=%%i
set state=shut down
set skip=0
for /f "tokens=5,6,7" %%a in ('ping -n 1 !ipaddr!') do (
    if "x%%b"=="xunreachable." set skip=1
    if !skip!==0 if "x%%a"=="xReceived" if "x%%c"=="x1,"  set state=still on
)
echo %%i %%j is !state!

)
pause
endlocal

rem /IP ADDRESS0/COMPUTER NAME0
rem /IP ADDRESS1/COMPUTER NAME1

如果您确实需要修改此代码,请注意:

for /f "tokens=2,3 delims=/ skip=16" %%i in (CheckPCs.bat) do (

for 循环一次处理一行 CheckPCs.bat。 Skip 告诉它忽略前 16 行并直接访问 IP 地址。我没有特殊原因使用 / 作为分隔符,但请注意,如果您要 ping 网址而不是 IP,则必须更改分隔符。像管道字符这样的东西|会工作。当然,由于该行用 rem 注释掉,因此 rem 成为第一个标记,这意味着我只想使用标记 2 和 3,它们将是 IP 地址和 PC 描述。后一个字段是可选的,您只需修改代码即可将其删除。

您可能应该修改用于状态和回显的术语 %%i %%j 是 !state!以便术语对您来说清晰简洁。如果您想在某处记录状态,您可以通过将 >> file.txt 附加到该行将其输入到文本文件中。在这种情况下,您可能还想添加日期/时间。

最后,受过适当编码培训的人可能知道,带有标记的批处理 for 循环的工作方式(简单来说)是文本的每个部分在每个分隔符处拆分,默认为空格,然后它被分配给一个 %% 变量,其名称以您指定的任何字符开头,然后在 ascii 字符列表中递增。这意味着如果我指定从 %%i 开始,下一个标记将是 %%j,然后是 %%k,依此类推。如果我使用 %%B,接下来是 %%C,然后是 %%D 等等。我读到的关于该主题的每个线程最多可以有 31 个标记。

答案 9 :(得分:-1)

我已经看到了ping的三个结果 - 我们想要的那个&#34;知识产权回复的地方,&#34; Host Unreachable&#34;并且&#34;超时&#34; (不确定准确的措辞)。

前两个返回ERRORLEVEL为0。

超时返回ERRORLEVEL为1。

是否可能返回其他结果和错误级别? (除了使用一个无效的开关,它返回允许的开关,错误级别为1.)

显然无法访问的主机可以使用以前发布的方法之一(尽管很难弄清楚当有人回复他们正在编写代码的情况时)但是超时会以类似的方式返回它可以被解析吗?

一般来说,如何知道可以解析ping的哪一部分结果? (即,为什么发送和/或接收和/或TTL可以解析,但主机无法访问?

哦,还有iSid,也许没有多少赞成票,因为阅读此内容的人没有足够的积分。所以他们回答(或不回答)他们的问题并离开。

我没有将上述内容作为答案发布。它应该是一个评论,但我没有看到这个选择。

答案 10 :(得分:-1)

#!/bin/bash
logPath="pinglog.txt"

while(true)
      do
          # refresh the timestamp before each ping attempt
          theTime=$(date -Iseconds)

          # refresh the ping variable
          ping google.com -n 1

            if [ $? -eq 0 ] 
            then
                 echo $theTime + '| connection is up' >> $logPath
            else
                 echo $theTime + '| connection is down' >> $logPath
          fi
            Sleep 1
             echo ' '
      done