Как проверить, ответил ли ping или нет в командном файле - PullRequest
39 голосов
/ 16 июня 2010

Я хочу постоянно пинговать сервер и видеть окно сообщения, когда оно отвечает, то есть сервер в данный момент не работает. Я хочу сделать это через командный файл.

Я могу показать окно сообщения, как здесь сказано Показать всплывающее окно / окно сообщения из пакетного файла Windows

и может непрерывно пинговать по

ping <servername> -t

Но как мне проверить, ответил он или нет?

Ответы [ 10 ]

28 голосов
/ 15 августа 2010

Вопрос был в том, чтобы узнать, ответил ли ping, что делает этот скрипт.

Однако это не будет работать, если вы получите сообщение Host Unreachable, так как оно возвращает ERRORLEVEL 0 и проходит проверку для Received = 1, использованной в этом сценарии, возвращая Link is UP из сценария. Host Unreachable возникает, когда ping доставлен целевому notwork, но удаленный хост не найден.

Если я вспоминаю, как правильно проверить, был ли успешен пинг, - это найти строку «TTL» с помощью Find.

@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 не будет отображать TTL при получении ответа от адреса IPv6.

19 голосов
/ 16 июня 2010

Следующая программа checklink.cmd - хорошее место для начала. Он основан на том факте, что вы можете выполнить одиночный пинг и что в случае успеха на выходе будет строка:

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 для испанского. Сделайте пробный пинг, чтобы узнать, какое ключевое слово используется в вашем регионе.


Чтобы уведомлять вас только при изменении состояния , вы можете использовать:

@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

Тем не менее, как отметил Гейб в комментарии, вы можете просто использовать 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
6 голосов
/ 04 октября 2016

Я знаю, что это старый поток, но я хотел проверить, была ли машина в моей системе, и, если я не понял неправильно, ничего из вышеперечисленного не работает, если мой маршрутизатор сообщает, что адрес недоступен. Я использую командный файл, а не сценарий, потому что я хотел «поцеловать» практически на любой машине WIN. Таким образом, подход, который я использовал, заключался в том, чтобы сделать более одного пинга и проверить на «Lost = 0» следующим образом

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

Я не проверял это строго, но пока он делает работу за меня

1 голос
/ 27 мая 2016

Я сделал вариант решения на основе сообщения 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

Звонок на waitlink будет возвращаться только при успешном пинге.Спасибо Паксдиабло и Гейбу.Надеюсь, это поможет кому-то еще.

0 голосов
/ 07 февраля 2018
#!/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
0 голосов
/ 14 мая 2017

Надеюсь, это кому-нибудь поможет.Я использую эту логику, чтобы проверить, реагируют ли сетевые ресурсы перед проверкой отдельных путей.Он должен обрабатывать DNS-имена и IP-адреса

Допустимый путь в текстовом файле: \ 192.168.1.2 \ 'folder' или \ NAS \ 'folder'

@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
0 голосов
/ 20 ноября 2016

Вот что я нашел:

: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 секунду, но работает только при подключении к сети

0 голосов
/ 17 октября 2014

Я видел три результата для пинга - тот, который нам «нужен», когда IP отвечает, «Host Unreachable» и «timed out» (не уверен в точной формулировке).

Первые дваreturn ERRORLEVEL = 0.

Тайм-аут возвращает ERRORLEVEL 1. 1. 1005 *

Могут ли быть возвращены другие результаты и уровни ошибок?(Помимо использования недопустимого переключателя, который возвращает допустимые параметры и уровень ошибки 1.)

Видимо, Host Unreachable может использовать один из ранее опубликованных методов (хотя трудно определить, когда кто-то отвечает, в каком случае онписать код для), но получается ли время ожидания таким же образом, чтобы его можно было проанализировать?

В общем, как узнать, какая часть результатов пинга может быть проанализирована?(То есть, почему отправленные и / или полученные и / или TTL могут быть проанализированы, но не доступны для хоста?

Да, и iSid, возможно, не так много голосов, потому что люди, которые читают это, не имеютдостаточно очков. Таким образом, они получают ответ на свой вопрос (или нет) и уходят.

Я не публиковал вышеизложенное в качестве ответа. Это должен был быть комментарий, но я не видел этого выбора.

0 голосов
/ 01 июля 2014

Простая версия:

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
)

)

Но иногда первый пинг просто терпит неудачу, а второй работает (или наоборот), верно? Поэтому мы хотим добиться успеха, если хотя бы один ответ 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
)
)

)
0 голосов
/ 16 июня 2010

Вы можете пропинговать без "-t" и проверить код завершения пинга.Он сообщает об ошибке, когда нет ответа.

...