Batch ERRORLEVEL ping response

2019-01-23 06:45发布

I'm trying to use a batch file to confirm a network connection using ping. I want to do batch run and then print if the ping was successful or not. The problem is that it always displays 'failure' when run as a batch. Here is the code:

@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' is the name of my computer. I'm having my computer ping itself so I can eliminate the variable of a poor connection. As I said before, the batch always results in failure. Oddly enough, the program works fine if I copy the code into the command prompt. Does anyone know why the program works fine in the command prompt but doesn't work as a batch? Thanks

13条回答
混吃等死
2楼-- · 2019-01-23 07:22
ping 198.168.57.98 && echo Success || echo failed
查看更多
Deceive 欺骗
3楼-- · 2019-01-23 07:24

I 'm not exactly sure what the interaction between FIND and setting the error level is, but you can do this quite easily:

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

This prints 0 if the ping failed, 1 if it succeeded. I made it look for just "0% loss" (not specifically 4 pings) so that the number of pings can be customized.

The percent sign has been doubled so that it's not mistaken for a variable that should be substituted.

The FOR trick serves simply to set the output of a command as the value of an environment variable.

查看更多
淡お忘
4楼-- · 2019-01-23 07:27

ping has an errorlevel output value. Success is 0, failure is 1. Just do this:

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

As you can see there is no need for all this scripting overkill.

查看更多
贼婆χ
5楼-- · 2019-01-23 07:30

A more reliable ping error checking method:

@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.
)

This works by checking whether a string such as 69 ms or 314ms is printed by ping.

(Translated versions of Windows may print 42 ms (with the space), hence we check for that.)

Reason:

Other proposals, such as matching time= or TTL are not as reliable, because pinging IPv6 addresses doesn't show TTL (at least not on my Windows 7 machine) and translated versions of Windows may show a translated version of the string time=. Also, not only may time= be translated, but sometimes it may be time< rather than time=, as in the case of time<1ms.

查看更多
叼着烟拽天下
6楼-- · 2019-01-23 07:32

The most simple solution to this I can think of:

set error=failure
ping racer -n 1 -w 100>nul 2>&1 && set error=success

Of course, -w needs to be adjusted if on a slow link (100ms might be too short over Dialup ;-))

regards

查看更多
乱世女痞
7楼-- · 2019-01-23 07:33

Testing for 0% loss may give a false positive, in this scenario: Let's say you normally have a network drive on some_IP-address, and you want to find out whether or not it's on.

If that drive is off, and you ping some_IP-address, the IP address from which you ping, will respond:
Answer from your_own_IP-address: target host not reachable
... 0% loss

You might be better off using if exist or if not exist on that network location.

查看更多
登录 后发表回答