web-dev-qa-db-fra.com

Comment vérifier si ping a répondu ou non dans un fichier batch

Je souhaite envoyer en permanence un ping à un serveur et voir une boîte de message chaque fois qu'il répond, c'est-à-dire que le serveur est actuellement hors service. Je veux le faire par fichier de commandes.

Je peux afficher une boîte de message comme indiqué ici Afficher une fenêtre contextuelle/une boîte de message à partir d'un fichier de commandes Windows

et peut cingler en continu par 

ping <servername> -t

Mais comment puis-je vérifier si cela a répondu ou non?

37
IsmailS

Le programme checklink.cmd suivant est un bon point de départ. Cela repose sur le fait que vous pouvez faire un ping unique et que, en cas de succès, la sortie contiendra la ligne:

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

En extrayant les jetons 5 et 7 et en les vérifiant respectivement "Received" et "1,", vous pouvez détecter le succès.

@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

Appelez-le avec le nom (ou l'adresse IP) que vous souhaitez tester:

checklink 127.0.0.1
checklink localhost
checklink nosuchaddress

Tenez compte du fait que, si vos paramètres régionaux ne sont pas l'anglais, vous devez remplacer Received par le mot clé correspondant dans vos paramètres régionaux, par exemple recibidos pour l'espagnol. Faites un test de ping pour découvrir quel mot-clé est utilisé dans vos paramètres régionaux.


Pour ne vous avertir que lorsque l'état change , vous pouvez utiliser:

@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

Cependant, comme le souligne Gabe dans un commentaire, vous pouvez simplement utiliser ERRORLEVEL pour que l'équivalent de ce deuxième script ci-dessus devienne:

@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
18
paxdiablo

La question était de voir si le ping répondait à ce script.

Toutefois, cela ne fonctionnera pas si vous recevez le message Host Unreachable, qui renvoie ERRORLEVEL 0 et transmet la vérification de Received = 1 utilisé dans ce script, en renvoyant Link is UP à partir du script. L'hôte inaccessible se produit lorsque le ping a été remis à la cible Notwork mais que l'hôte distant est introuvable.

Si je me souviens bien, la bonne façon de vérifier si le ping était un succès est de rechercher la chaîne 'TTL' à l'aide de 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%

Cela ne fonctionnera pas avec les réseaux IPv6 car le ping ne listera pas TTL lors de la réception d'une réponse depuis une adresse IPv6.

26
Lukasz

Je sais que c'est un vieux fil, mais je voulais vérifier si une machine était en place sur mon système et, sauf si je me suis mal compris, rien de ce qui précède ne fonctionne si mon routeur indique qu'une adresse est inaccessible. J'utilise un fichier batch plutôt qu'un script parce que je voulais "KISS" sur à peu près n'importe quelle machine WIN. Donc, l’approche que j’avais utilisée était de faire plus d’un ping et de tester "Lost = 0" comme suit

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

Je n'ai pas testé cela rigoureusement mais jusqu'à présent, il fait le travail pour moi

5
Bigrog

J'ai créé une variante basée sur le message de paxdiablo

Placez le code suivant dans 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

Par exemple, utilisez-le depuis un autre fichier de commandes comme celui-ci.

call Waitlink someurl.com
Net Use o: \\someurl.com\myshare

L'appel à waitlink ne sera renvoyé que lorsqu'un ping réussira. Merci à paxdiablo et à Gabe. J'espère que ceci aide quelqu'un d'autre.

1
Jan Lauridsen

Voici quelque chose que j'ai trouvé:

: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
) 

Notez que ping 1.1.1.1 -n -w 1000 >NUL attend 1 seconde mais ne fonctionne que lorsqu'il est connecté à un réseau

0
Juggler

Version simple:

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
)

)

Mais parfois, le premier ping échoue et le second fonctionne (ou vice versa), non? Nous voulons donc avoir du succès lorsqu'au moins une réponse ICMP a été renvoyée avec succès:

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
damian1baran

J'espère que ça aidera quelqu'un. J'utilise ce bit de logique pour vérifier si les partages réseau sont réactifs avant de vérifier les chemins individuels. Il devrait gérer les noms DNS et les adresses IP

Un chemin valide dans le fichier texte serait \192.168.1.2\'dossier' ou\NAS\'dossier'

@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
Dan W

Vous pouvez faire un ping sans "-t" et vérifier le code de sortie du ping. Il signale un échec lorsqu'il n'y a pas de réponse.

0
Rotsor