批处理ERRORLEVEL ping响应

12

我正在尝试使用批处理文件通过ping确认网络连接。我想要批量运行,然后打印出ping是否成功。问题在于当作为批处理运行时,它总是显示“失败”。以下是代码:

@echo off
cls
ping racer | find "Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"
if not errorlevel 1 set error=success
if errorlevel 1 set error=failure
cls
echo Result: %error%
pause

'racer' 是我电脑的名称。我正在让电脑对自身进行ping测试,以排除网络连接质量差的可能性。就像我之前说过的,批处理程序总是失败。奇怪的是,如果我将代码复制到命令提示符中,程序就可以正常运行。是否有人知道为什么在命令提示符中可以正常运行而作为批处理却不行呢? 谢谢。

13个回答

32

一种更可靠的ping错误检查方法:

@echo off
set "host=192.168.1.1"

ping -n 1 "%host%" | findstr /r /c:"[0-9] *ms"

if %errorlevel% == 0 (
    echo Success.
) else (
    echo FAILURE.
)

这个功能通过检查像69 ms314ms这样的字符串是否被ping打印出来来实现。

(翻译版本的Windows可能会打印带有空格的42 ms,因此我们要检查这种情况。)

原因:

其他提议,例如匹配time=TTL不够可靠,因为ping IPv6地址不显示TTL(至少在我的Windows 7机器上不显示),而且Windows的翻译版本可能会显示time=的翻译版本。另外,time=可能不仅被翻译,有时还可能是time<,就像time<1ms的情况一样。


4
“ms”也被翻译成其他语言(例如俄语)。 - littleguga
嗯,“ms”在法语Windows上运行良好。如果有人能够研究并发布具体信息,特别是“ms”会在哪些语言上失败,那就太好了。 - BuvinJ
/r和/c对我来说出了一些问题,似乎/c是默认的。我正在寻找当WiFi断开连接时的特定关键字,然后重新连接的解决方法。在我的情况下,正确的语法是“ping -n 1 google.cl | findstr"Compruebe agotado"”。 - Francisco A. Cerda

4
如果您想要...
echo "Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"

您会发现%已经被删除了。在批处理文件中,%有特殊含义,因此您需要对其进行转义:

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

然而,使用 TTL 作为成功的指示更加简单。
.. | find "TTL"

我在另一篇帖子中看到了有关使用“TTL”的内容,但想避免使用它,因为有人说它可能会返回错误的结果。 - LastStar007

4
测试0%的丢包率可能会出现错误的结果,例如在以下情况下:假设您通常使用一些IP地址上的网络驱动器,并且您想查找它是否开启。
如果该驱动器关闭并且您ping某个IP地址,则从中ping的IP地址将响应: 答复来自您自己的IP地址:目标主机不可达......0%丢失
在这种情况下,您最好在该网络位置上使用“if exist”或“if not exist”命令。

2

另一种不使用任何变量的变体

ping racer -n 1 -w 100>nul || goto :pingerror
...

:pingerror
echo Host down
goto eof

:eof
exit /b

2

我不确定FIND和设置错误级别之间的交互是什么,但你可以很容易地做到这一点:

@echo off
for /f %%i in ('ping racer ^| find /c "(0%% loss)"') do SET MATCHES=%%i
echo %MATCHES%

这将打印0如果ping失败,1如果成功。我让它只寻找"0% loss"(不是具体的4个ping),以便可以自定义ping的次数。
百分号已经加倍,以免被误认为是应该替换的变量。 FOR技巧仅仅是将命令的输出设置为环境变量的值。

谢谢你的帮助!这个链接(https://dev59.com/ZnA75IYBdhLWcg3w49UR)是我开始这个项目的地方,它的示例使用了FIND命令。 - LastStar007
3
可能无法正常工作。例如,当收到“主机不可达”的响应时,我遭受了%0的损失。 - moteus

1

是的,ping命令无法返回正确的错误级别。为了检查网络连接和计算机状态,我使用了“net view 计算机名称”命令,然后检查%errorlevel%——简单易行。


OP打算实现一种连接质量测试 - 因此需要进行多次ping并检查“0%丢失”。net view无法做到这一点。 - Stephan

0

ping 命令有一个错误级别输出值。成功为 0,失败为 1。 只需执行以下操作:

C:\>ping 4.2.2.2

Pinging 4.2.2.2 with 32 bytes of data:

Reply from 4.2.2.2: bytes=32 time=28ms TTL=57
Reply from 4.2.2.2: bytes=32 time=29ms TTL=57
Reply from 4.2.2.2: bytes=32 time=30ms TTL=57
Reply from 4.2.2.2: bytes=32 time=29ms TTL=57

Ping statistics for 4.2.2.2:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 28ms, Maximum = 30ms, Average = 29ms

C:\>echo %errorlevel%
0

C:\>ping foo.bar
Ping request could not find host foo.bar. Please check the name and try again.

C:\>echo %errorlevel%
1

正如您所看到的,没有必要进行过度编写脚本。


7
问题在于当主机未知时,错误级别(errorlevel)只会被设为1。如果你ping一个不响应的IP地址,它仍然会返回0。请注意,这里不提供解释和额外内容。 - l0ft13
同意。以下是进一步描述的情况:C:\>ping -n 1 172.25.0.1 正在 Ping 172.25.0.1 具有 32 字节的数据: 来自 172.25.1.1 的回复: 目标主机不可达。 172.25.0.1 的 Ping 统计信息: 数据包: 已发送 = 1,已接收 = 1,丢失 = 0 (0% 丢失), C:\>echo %errorlevel% 0 - jdw

0

首先

>@echo off
>for /f %%i in ('ping racer ^| find /c "(0%% loss)"') do SET MATCHES=%%i
>echo %MATCHES%

不起作用。如果它不失败,它将检测到0%,因为它是0%。 如果它失败了,也不会起作用,因为它将有100%的损失,这意味着它在10后面找到了0%的损失部分 10(0%的损失)

让它检测100%的损失,像这样:

>for /f %%i in ('ping  -n 1 -l 1 %pc% ^| find /c "(100%% loss)"') do SET check=%%i

错误级别可能有点混乱,但它的工作效果非常好:

>if '%check%'=='1' goto fail
>if '%check%'=='0' echo %pc% is online.&goto starting

1 表示失败 0 表示成功

在我的脚本中使用链接。 Goto fail 将转到我的脚本中的 :fail,该脚本将向我发送消息,指出 %pc%(用户在开始时输入)处于离线状态,并进行另一次运行。

>:fail
>color 0c
>title %pc% is offline
>echo %pc% is offline
>PING -n 6 127.0.0.1>nul
>goto choice

希望对您有所帮助。


0
我能想到的最简单的解决方案是:
set error=failure
ping racer -n 1 -w 100>nul 2>&1 && set error=success

当然,如果在慢速网络上(例如拨号连接),需要调整-w参数的值(100毫秒可能太短了)。

祝好!


0

我需要重置wifi连接,因为它出现了问题。这是我的快速解决方案。

@echo off
Rem Microsoft Windows 10 ping test to gateway.
Rem Run batch file from an administrative command prompt.

cls
:starting
Rem Send one ping to the gateway.  Write the results to a file.
ping 192.168.1.1 -n 1 > pingtest.txt

Rem Search for unreachable in the file. 
c:\windows\system32\findstr.exe "unreachable" pingtest.txt

Rem errorlevel 0 reset the adapter if 1 then wait 10 minutes and test again
if %errorlevel%==1 goto waiting

Rem unreachable was found reset the adapter.

Rem write the date and time the reset was done.
echo Reset date: %date% time: %time% >> resettimes.txt

Rem issue netsh interface show interface to find your adapter's name to reset
Rem my adapter is "wi-fi"

netsh interface set interface "wi-fi" disable
timeout /t  5
netsh interface set interface "wi-fi" enable
:waiting
echo "It is online waiting 10 minutes"
timeout /t  600
goto starting

1
不要(试图)回答问题。 - Stephan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接