代码之家  ›  专栏  ›  技术社区  ›  IsmailS

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

  •  38
  • IsmailS  · 技术社区  · 14 年前

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

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

    能不停地蹦蹦

    ping <servername> -t
    

    但我如何检查它是否响应?

    10 回复  |  直到 6 年前
        1
  •  19
  •   Krpan    7 年前

    以下 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
  •  26
  •   Lukasz    14 年前

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

    但是,如果您收到主机无法访问的消息,这将不起作用,因为这将返回错误级别0,并通过检查此脚本中使用的received=1,返回链接从脚本启动。当Ping传递到目标NotWork但找不到远程主机时,会发生主机无法访问。

    如果我记得检查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网络,因为ping在接收来自IPv6地址的答复时不会列出TTL。

        3
  •  5
  •   Bigrog    8 年前

    我知道这是一个旧的线程,但是我想测试一台机器是否在我的系统上运行,除非我误解了,如果我的路由器报告一个地址是不可访问的,上面的任何一个都不会工作。我使用的是批处理文件而不是脚本,因为我想在几乎所有的赢机器上“亲吻”。因此,我使用的方法是执行多个ping并测试“lost=0”,如下所示

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

    我没有严格地测试过,但到目前为止,它对我来说是有用的。

        4
  •  1
  •   Jan Lauridsen    8 年前

    我已经根据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的调用才会返回。多亏了帕西亚布洛和加布。希望这能帮助别人。

        5
  •  0
  •   Rotsor    14 年前

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

        6
  •  0
  •   damian1baran    10 年前

    简单版本:

    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失败了,第二个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
    )
    )
    
    )
    
        7
  •  0
  •   fotNelton    8 年前

    我发现了一些东西:

    :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秒,但仅在连接到网络时工作

        8
  •  0
  •   Dan W    7 年前

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

    文本文件中的有效路径为 \ 192.168.1.2“文件夹”或“文件夹”

    @echo off
    title Network Folder Check
    
    pushd "%~dp0"
    :00
    cls
    
    for /f "delims=\\" %%A in (Files-to-Check.txt) do set Server=%%A
        setlocal EnableDelayedExpansion
            ping -n 1 %Server% | findstr TTL= >nul 
                if %errorlevel%==1 ( 
                    ping -n 1 %Server% | findstr "Reply from" | findstr "time" >nul
                        if !errorlevel!==1 (echo Network Asset %Server% Not Found & pause & goto EOF)
                )
    :EOF
    
        9
  •  -1
  •   Phil Reinemann    10 年前

    我看到了Ping的三个结果——我们“想要”的结果,其中IP回复,“主机无法访问”和“超时”(不确定确切的措辞)。

    前两个返回错误级别0。

    超时返回错误级别1。

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

    显然,host unreachable可以使用以前发布的方法之一(虽然很难确定何时有人回复他们为哪个案例编写代码),但是是否以可以解析的类似方式返回超时?

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

    哦,还有伊希德,也许没有多少赞成票,因为读到这篇文章的人没有足够的分数。所以他们得到了他们的问题的回答(或者没有),然后离开了。

    我没有把上面的内容作为答案。这应该是一个评论,但我没有看到这个选择。

        10
  •  -1
  •   Tal    6 年前
    #!/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