Ping des serveurs en Python

167

En Python, existe-t-il un moyen d'envoyer une requête ping à un serveur via ICMP et de renvoyer TRUE si le serveur répond, ou FALSE s'il n'y a pas de réponse?

Kudu
la source
1
Related: Ping un site en Python?
jfs

Réponses:

112

Cette fonction fonctionne dans n'importe quel système d'exploitation (Unix, Linux, macOS et Windows)
Python 2 et Python 3

EDITS:
Par @radato a os.system été remplacé par subprocess.call. Cela évite la vulnérabilité d' injection de shell dans les cas où votre chaîne de nom d'hôte pourrait ne pas être validée.

import platform    # For getting the operating system name
import subprocess  # For executing a shell command

def ping(host):
    """
    Returns True if host (str) responds to a ping request.
    Remember that a host may not respond to a ping (ICMP) request even if the host name is valid.
    """

    # Option for the number of packets as a function of
    param = '-n' if platform.system().lower()=='windows' else '-c'

    # Building the command. Ex: "ping -c 1 google.com"
    command = ['ping', param, '1', host]

    return subprocess.call(command) == 0

Notez que, selon @ikrase sous Windows, cette fonction reviendra toujours Truesi vous obtenez une Destination Host Unreachableerreur.

Explication

La commande est pingà la fois dans les systèmes Windows et Unix.
L'option -n(Windows) ou -c(Unix) contrôle le nombre de paquets qui dans cet exemple a été défini sur 1.

platform.system()renvoie le nom de la plateforme. Ex. 'Darwin'sur macOS.
subprocess.call()effectue un appel système. Ex. subprocess.call(['ls','-l']).

ePi272314
la source
14
Notez que cela retournera toujours vrai (sous Windows) si vous obtenez une réponse "hôte de destination inaccessible" d'un autre hôte.
ikrase
Je trouve que j'obtiendrai occasionnellement un succès de ping lorsque mon modem est éteint ??? Cela teste "8.8.8.8" et "google.com" sur un système d'exploitation Windows 10. Quelque chose ne va pas.
Markus
Cela ne peut pas arriver @Markus. S'il vous plaît, testez à la main et avec une version modifiée du code ci-dessus, et dites-nous le résultat. À la main: 1) ouvrir cmd 2) ping 8.8.8.8 -n 13) echo %ERRORLEVEL%. Code: modifiez la dernière ligne du code Python en return system_call(command). Avec une connectivité appropriée, vous obtiendrez 0 (zéro). Avec votre modem éteint, vous devez obtenir un code d'erreur. Bien entendu, les deux méthodes doivent renvoyer le même code d'erreur dans les mêmes conditions.
ePi272314
Cela s'est produit et j'utilisais le code exact, mot pour mot. Je comprends et je crois vos commentaires, il n'y a aucun moyen qu'un ping en ligne de commande puisse réussir quand il n'y a pas de connexion, d'où ma pensée que quelque chose ne fonctionnait pas correctement dans l'opération python en ligne de commande. Je vais essayer la mise à jour et voir comment ça se passe. Merci.
Markus
@Markus voir le commentaire d'ikrase.
Boris
163

Si vous n'avez pas besoin de prendre en charge Windows, voici une façon très concise de le faire:

import os
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)

#and then check the response...
if response == 0:
  print hostname, 'is up!'
else:
  print hostname, 'is down!'

Cela fonctionne car le ping renvoie une valeur différente de zéro si la connexion échoue. (La valeur de retour diffère en fait en fonction de l'erreur réseau.) Vous pouvez également modifier le délai d'expiration du ping (en secondes) à l'aide de l'option «-t». Notez que cela affichera du texte sur la console.

10 flux
la source
42
J'ai fini avec cette varianteresponse = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
MGP
4
@ jeckyll2hide man ping, envoyez juste 1 paquet avec un délai de 2 secondes et redirigez toute la sortie vers / dev / null, récupérez uniquement la valeur de retour.
MGP
@ManuelGutierrez Je pense que vous voulez "-W 2000" (timeout après 2000 millisecondes) et peut-être "-t 3" (sortie après 3 secondes, quoi qu'il
arrive
1
-w et -W prennent des valeurs en secondes et non en millisecondes. Vérifiez man pingpour être sûr.
Alan Turing
7
Si vous obtenez la hostnamechaîne d'un utilisateur, il pourrait facilement pirater votre serveur en vous donnant une "URL" comme 'google.com; rm -rf /*'. Utilisez subprocess.run(["ping", "-c", "1", hostname]).returncodeplutôt.
Boris
38

Il existe un module appelé pyping qui peut le faire. Il peut être installé avec pip

pip install pyping

Il est assez simple à utiliser, cependant, lorsque vous utilisez ce module, vous avez besoin d'un accès root car il crée des paquets bruts sous le capot.

import pyping

r = pyping.ping('google.com')

if r.ret_code == 0:
    print("Success")
else:
    print("Failed with {}".format(r.ret_code))
Stephen Cochran
la source
4
"Notez que les messages ICMP ne peuvent être envoyés qu'à partir de processus exécutés en tant que root (sous Windows, vous devez exécuter ce script en tant qu'Administrateur)."
Ben Hyde
1
J'aime que vous puissiez spécifier le délai d'expiration et le nombre de demandes ICMP envoyées. J'ai pu écrire un script qui découvre tous les hôtes sur le sous-réseau local. Il s'exécute en 1 seconde, au lieu de 255 secondes en utilisant la os.system('ping -c 1 -t 1 hostname')solution. De plus, la pypingbibliothèque est très facile à utiliser par rapport à l'utilisation de la bibliothèque de sockets TCP / IP. J'ai écrit mon programme ping en utilisant les deux, et il pypingest beaucoup plus rapide et plus facile à utiliser, à mon avis, surtout si l'on n'est pas familier avec l'utilisation de la bibliothèque de sockets TCP / IP.
MikeyE
10
ne fonctionne pas avec py3. ModuleNotFoundError: Aucun module nommé 'core'
alireza
2
l'erreur 'core' provient d'une incompatibilité avec python3. J'ai essayé de le réparer pour python3 mais il continue de m'envoyer des erreurs. la page github des auteurs et des projets est en panne (404 non trouvés). nous devrons le porter nous-mêmes sur python3 :-)
Andre
6
pour python3, essayez ping3: github.com/kyan001/ping3 pip install ping3
beep_check
29
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
mluebke
la source
6
Le seul problème avec cela est que cela ne fonctionnerait pas sous Windows.
Kudu
8
Il convient de mentionner que la raison pour laquelle quelque chose comme celui-ci est nécessaire est que ICMP nécessite root, et / bin / ping contourne cela en étant défini SUID.
Catskul
1
Remarque: peut échouer si le ping est dans un emplacement différent. Utilisez whereis pingpour obtenir le chemin correct.
octern
4
Cela fonctionne sous Windows:ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Victor Lellis
1
Comment puis-je analyser le résultat pour vérifier si la réponse était ok ou ko sous Windows?
Pitto
15

Pour python3, il existe un module python ping3 très simple et pratique : ( pip install ping3, nécessite les privilèges root ).

from ping3 import ping, verbose_ping
ping('example.com')  # Returns delay in seconds.
>>> 0.215697261510079666

Ce module permet également la personnalisation de certains paramètres.

Александр Рублев
la source
2
Comme modifié nécessite des privilèges root, discussion sur la suppression de
Dimitrios Mistriotis
1
Oh, besoin de privilège root non seulement pour l'installation, mais aussi pour l'exécution: ping ("example.com")
Horloge ZHONG
14

Parce que j'aime avoir mon programme Python universel sur les versions 2.7 et 3.x et sur les plateformes Linux, Mac OS et Windows, j'ai dû modifier les exemples existants.

# shebang does not work over all platforms
# ping.py  2016-02-25 Rudolf
# subprocess.call() is preferred to os.system()
# works under Python 2.7 and 3.4
# works under Linux, Mac OS, Windows

def ping(host):
    """
    Returns True if host responds to a ping request
    """
    import subprocess, platform

    # Ping parameters as function of OS
    ping_str = "-n 1" if  platform.system().lower()=="windows" else "-c 1"
    args = "ping " + " " + ping_str + " " + host
    need_sh = False if  platform.system().lower()=="windows" else True

    # Ping
    return subprocess.call(args, shell=need_sh) == 0

# test call
print(ping("192.168.17.142"))
Rudolf
la source
1
Au lieu de cela, False if platform.system().lower()=="windows" else Truevous pouvez bien sûr également utiliser platform.system().lower() != "windows".
Frerich Raabe
Ça ne os.name!="nt"marche pas aussi? Certes, je ne l'ai pas essayé sur tous les combos ver / plateforme!
Keeely
2
Dans mon cas, la passerelle par défaut renvoie un message «inaccessible», mais la commande windows ping a toujours un code retour de 0. Donc, cette approche a fonctionné (désolé pour le formatage - ses 6 lignes, y compris la déclaration de fonction): def ping(host): process = subprocess.Popen(["ping", "-n", "1",host], stdout=subprocess.PIPE, stderr=subprocess.PIPE) streamdata = process.communicate()[0] if 'unreachable' in str(streamdata): return 1 return process.returncode
wellspokenman
@wellspokenman vous préféreriez renvoyer 0 s'il unreachablese trouve dans le tube, non?
beeb
1
@beeb ouais j'ai fait ça aussi mais j'ai oublié de mettre à jour le commentaire. Ma fonction actuelle ressemble à ceci: pastebin.com/FEYWsVjK
wellspokenman
8

Après avoir regardé autour de moi, j'ai fini par écrire mon propre module ping, conçu pour surveiller un grand nombre d'adresses, est asynchrone et n'utilise pas beaucoup de ressources système. Vous pouvez le trouver ici: https://github.com/romana/multi-ping/ Il est sous licence Apache, vous pouvez donc l'utiliser dans votre projet comme bon vous semble.

Les principales raisons de la mise en œuvre de la mienne sont les restrictions des autres approches:

  • La plupart des solutions mentionnées ici nécessitent une exécution vers un utilitaire de ligne de commande. C'est assez inefficace et gourmand en ressources si vous devez surveiller un grand nombre d'adresses IP.
  • D'autres mentionnent des modules de ping python plus anciens. J'ai regardé ceux-ci et à la fin, ils ont tous eu un problème ou un autre (comme ne pas définir correctement les ID de paquet) et n'ont pas géré le ping d'un grand nombre d'adresses.
Juergen Brendel
la source
Bon travail, mon pote! Si quelqu'un veut le voir en action, il suffit d'utiliser github.com/romana/multi-ping/blob/master/demo.py
Cucu
7
#!/usr/bin/python3

import subprocess as sp

def ipcheck():
    status,result = sp.getstatusoutput("ping -c1 -w2 " + str(pop))
    if status == 0:
        print("System " + str(pop) + " is UP !")
    else:
        print("System " + str(pop) + " is DOWN !")


pop = input("Enter the ip address: ")
ipcheck()
Udayendu
la source
Ce code peut avoir la réponse à la question, mais il serait utile d'ajouter quelques commentaires ou une explication sur la façon dont votre code résout le problème.
skrrgwasme
5

Assurez-vous que pyping est installé ou installez-le pip install pyping

#!/usr/bin/python
import pyping

response = pyping.ping('Your IP')

if response.ret_code == 0:
    print("reachable")
else:
    print("unreachable")
Naveen
la source
1
Merci! Cependant, je dois exécuter ce code en tant que root pour le faire fonctionner.
Thomas
1
La page GitHub de Pyping n'existe plus et le package PyPI n'a pas été mis à jour depuis 2016.
Stevoisiak
J'ai eu les erreurs suivantes: import pyping Traceback (dernier appel en dernier): Fichier "<stdin>", ligne 1, dans <module> File "/usr/local/lib/python3.6/dist-packages/pyping/__init__. py ", ligne 3, dans <module> à partir de l'importation du noyau * ModuleNotFoundError: Aucun module nommé 'core'
Horloge ZHONG
5

Le ping ICMP programmatique est compliqué en raison des privilèges élevés requis pour envoyer des paquets ICMP bruts, et l'appel pingbinaire est moche. Pour la surveillance du serveur, vous pouvez obtenir le même résultat en utilisant une technique appelée ping TCP :

# pip3 install tcping
>>> from tcping import Ping
# Ping(host, port, timeout)
>>> ping = Ping('212.69.63.54', 22, 60)
>>> ping.ping(3)
Connected to 212.69.63.54[:22]: seq=1 time=23.71 ms
Connected to 212.69.63.54[:22]: seq=2 time=24.38 ms
Connected to 212.69.63.54[:22]: seq=3 time=24.00 ms

En interne, cela établit simplement une connexion TCP au serveur cible et la supprime immédiatement, en mesurant le temps écoulé. Cette implémentation particulière est un peu limitée en ce qu'elle ne gère pas les ports fermés, mais pour vos propres serveurs, cela fonctionne plutôt bien.

Kravietz
la source
4
#!/usr/bin/python3

import subprocess as sp

ip = "192.168.122.60"
status,result = sp.getstatusoutput("ping -c1 -w2 " + ip)

if status == 0: 
    print("System " + ip + " is UP !")
else:
    print("System " + ip + " is DOWN !")
Udayendu
la source
3

Je résous ceci avec:

def ping(self, host):
    res = False

    ping_param = "-n 1" if system_name().lower() == "windows" else "-c 1"

    resultado = os.popen("ping " + ping_param + " " + host).read()

    if "TTL=" in resultado:
        res = True
    return res

"TTL" est le moyen de savoir si le ping est correctement. Saludos

user3620655
la source
3

Ma réduction en utilisant les idées des réponses dans cet article, mais uniquement en utilisant le nouveau module de sous-processus recommandé et python3:

import subprocess
import platform

operating_sys = platform.system()
nas = '192.168.0.10'

def ping(ip):
    # ping_command = ['ping', ip, '-n', '1'] instead of ping_command = ['ping', ip, '-n 1'] for Windows
    ping_command = ['ping', ip, '-n', '1'] if operating_sys == 'Windows' else ['ping', ip, '-c 1']
    shell_needed = True if operating_sys == 'Windows' else False

    ping_output = subprocess.run(ping_command,shell=shell_needed,stdout=subprocess.PIPE)
    success = ping_output.returncode
    return True if success == 0 else False

out = ping(nas)
print(out)
Arno
la source
1
Vous n'avez pas besoin d'utiliser True if condition else Falsepour renvoyer True ou False en fonction d'une condition. Il suffit d'utiliser eg shell_needed = operating_sys == 'Windows'etreturn success == 0
emorris
2

Ce script fonctionne sur Windows, et devrait fonctionner sur d'autres OS: Il fonctionne sur Windows, Debian et macosx, nécessite un test sur solaris.

import os
import platform


def isUp(hostname):

    giveFeedback = False

    if platform.system() == "Windows":
        response = os.system("ping "+hostname+" -n 1")
    else:
        response = os.system("ping -c 1 " + hostname)

    isUpBool = False
    if response == 0:
        if giveFeedback:
            print hostname, 'is up!'
        isUpBool = True
    else:
        if giveFeedback:
            print hostname, 'is down!'

    return isUpBool

print(isUp("example.com")) #Example domain
print(isUp("localhost")) #Your computer
print(isUp("invalid.example.com")) #Unresolvable hostname: https://tools.ietf.org/html/rfc6761
print(isUp("192.168.1.1")) #Pings local router
print(isUp("192.168.1.135")) #Pings a local computer - will differ for your network
Matthieu
la source
Bonne réponse. Aucun droit d'administrateur requis pour Windows ici.
mountainclimber
Je reçois de toute façon Vrai à la fois une bonne et une mauvaise adresse IP
joash
Ouais cela ne fonctionne certainement pas.
Renvoie
2

J'ai fini par trouver cette question concernant un scénario similaire. J'ai essayé le pyping mais l'exemple donné par Naveen n'a pas fonctionné pour moi sous Windows sous Python 2.7.

Un exemple qui a fonctionné pour moi est:

import pyping

response = pyping.send('Your IP')

if response['ret_code'] == 0:
    print("reachable")
else:
    print("unreachable")
Templier
la source
1
pypingne semble pas être un module standard. Peut-être pourriez-vous fournir un lien?
Mawg dit de réintégrer Monica
2

En utilisant Multi-ping ( pip install multiPing), j'ai créé ce code simple ( copiez et collez simplement si vous voulez! ):

from multiping import MultiPing

def ping(host,n = 0):
    if(n>0):
        avg = 0
        for i in range (n):
            avg += ping(host)
        avg = avg/n
    # Create a MultiPing object to test hosts / addresses
    mp = MultiPing([host])

    # Send the pings to those addresses
    mp.send()

    # With a 1 second timout, wait for responses (may return sooner if all
    # results are received).
    responses, no_responses = mp.receive(1)


    for addr, rtt in responses.items():
        RTT = rtt


    if no_responses:
        # Sending pings once more, but just to those addresses that have not
        # responded, yet.
        mp.send()
        responses, no_responses = mp.receive(1)
        RTT = -1

    return RTT

Usage:

#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)

Si vous voulez un seul échantillon, le deuxième paramètre " 10" peut être ignoré!

J'espère que ça aide!

Geraldo Neto
la source
4
bibliothèque géniale, mais nécessite des privilèges root.
Craynic Cai
2

Ma version d'une fonction ping:

  • Fonctionne sur Python 3.5 et versions ultérieures, sur Windows et Linux (devrait fonctionner sur Mac, mais ne peut pas le tester).
  • Sous Windows, renvoie False si la commande ping échoue avec «Hôte de destination inaccessible».
  • Et n'affiche aucune sortie, que ce soit sous forme de fenêtre pop-up ou en ligne de commande.
import platform, subprocess

def ping(host_or_ip, packets=1, timeout=1000):
    ''' Calls system "ping" command, returns True if ping succeeds.
    Required parameter: host_or_ip (str, address of host to ping)
    Optional parameters: packets (int, number of retries), timeout (int, ms to wait for response)
    Does not show any output, either as popup window or in command line.
    Python 3.5+, Windows and Linux compatible (Mac not tested, should work)
    '''
    # The ping command is the same for Windows and Linux, except for the "number of packets" flag.
    if platform.system().lower() == 'windows':
        command = ['ping', '-n', str(packets), '-w', str(timeout), host_or_ip]
        # run parameters: capture output, discard error messages, do not show window
        result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, creationflags=0x08000000)
        # 0x0800000 is a windows-only Popen flag to specify that a new process will not create a window.
        # On Python 3.7+, you can use a subprocess constant:
        #   result = subprocess.run(command, capture_output=True, creationflags=subprocess.CREATE_NO_WINDOW)
        # On windows 7+, ping returns 0 (ok) when host is not reachable; to be sure host is responding,
        # we search the text "TTL=" on the command output. If it's there, the ping really had a response.
        return result.returncode == 0 and b'TTL=' in result.stdout
    else:
        command = ['ping', '-c', str(packets), '-w', str(timeout), host_or_ip]
        # run parameters: discard output and error messages
        result = subprocess.run(command, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
        return result.returncode == 0

N'hésitez pas à l'utiliser comme vous le souhaitez.

José Francisco Lopez Pimentel
la source
1

Cela semble assez simple, mais m'a donné des crises. J'ai continué à obtenir "l'opération de socket ouverte icmp n'est pas autorisée" ou bien les solutions se bloqueraient si le serveur était hors ligne. Si, cependant, vous voulez savoir que le serveur est actif et que vous exécutez un serveur Web sur ce serveur, alors curl fera le travail. Si vous avez ssh et des certificats, alors ssh et une simple commande suffiront. Voici le code:

from easyprocess import EasyProcess # as root: pip install EasyProcess
def ping(ip):
    ping="ssh %s date;exit"%(ip) # test ssh alive or
    ping="curl -IL %s"%(ip)      # test if http alive
    response=len(EasyProcess(ping).call(timeout=2).stdout)
    return response #integer 0 if no response in 2 seconds
user2099484
la source
1

J'avais une exigence similaire, je l'ai donc implémentée comme indiqué ci-dessous. Il est testé sur Windows 64 bits et Linux.

import subprocess
def systemCommand(Command):
    Output = ""
    Error = ""     
    try:
        Output = subprocess.check_output(Command,stderr = subprocess.STDOUT,shell='True')
    except subprocess.CalledProcessError as e:
        #Invalid command raises this exception
        Error =  e.output 

    if Output:
        Stdout = Output.split("\n")
    else:
        Stdout = []
    if Error:
        Stderr = Error.split("\n")
    else:
        Stderr = []

    return (Stdout,Stderr)

#in main
Host = "ip to ping"
NoOfPackets = 2
Timeout = 5000 #in milliseconds
#Command for windows
Command = 'ping -n {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
#Command for linux 
#Command = 'ping -c {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
Stdout,Stderr = systemCommand(Command)
if Stdout:
   print("Host [{}] is reachable.".format(Host))
else:
   print("Host [{}] is unreachable.".format(Host))

Lorsque l'adresse IP n'est pas accessible, subprocess.check_output () lève une exception. Une vérification supplémentaire peut être effectuée en extrayant les informations de la ligne de sortie «Paquets: envoyés = 2, reçus = 2, perdus = 0 (0% de perte)».

Luminos
la source
1

Voici une solution utilisant le subprocessmodule Python et l' pingoutil CLI fourni par le système d'exploitation sous-jacent. Testé sous Windows et Linux. Prise en charge de la définition d'un délai d'expiration du réseau. N'a pas besoin de privilèges root (au moins sur Windows et Linux).

import platform
import subprocess

def ping(host, network_timeout=3):
    """Send a ping packet to the specified host, using the system "ping" command."""
    args = [
        'ping'
    ]

    platform_os = platform.system().lower()

    if platform_os == 'windows':
        args.extend(['-n', '1'])
        args.extend(['-w', str(network_timeout * 1000)])
    elif platform_os in ('linux', 'darwin'):
        args.extend(['-c', '1'])
        args.extend(['-W', str(network_timeout)])
    else:
        raise NotImplemented('Unsupported OS: {}'.format(platform_os))

    args.append(host)

    try:
        if platform_os == 'windows':
            output = subprocess.run(args, check=True, universal_newlines=True).stdout

            if output and 'TTL' not in output:
                return False
        else:
            subprocess.run(args, check=True)

        return True
    except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
        return False
Epoc
la source
0

Utilisez ceci, il est testé sur python 2.7 et fonctionne correctement, il renvoie le temps de ping en millisecondes en cas de succès et renvoie False en cas d'échec.

import platform,subproccess,re
def Ping(hostname,timeout):
    if platform.system() == "Windows":
        command="ping "+hostname+" -n 1 -w "+str(timeout*1000)
    else:
        command="ping -i "+str(timeout)+" -c 1 " + hostname
    proccess = subprocess.Popen(command, stdout=subprocess.PIPE)
    matches=re.match('.*time=([0-9]+)ms.*', proccess.stdout.read(),re.DOTALL)
    if matches:
        return matches.group(1)
    else: 
        return False
MSS
la source
0

Une chose que beaucoup de réponses manquent est que (au moins sous Windows) la pingcommande renvoie 0 (indiquant le succès) si elle reçoit la réponse «Hôte de destination inaccessible».

Voici mon code qui vérifie s'il b'TTL='est dans la réponse, car cela n'est présent que lorsque le ping a atteint l'hôte. Remarque: la plupart de ce code est basé sur les autres réponses ici.

import platform
import subprocess

def ping(ipAddr, timeout=100):
    '''
    Send a ping packet to the specified host, using the system ping command.
    Accepts ipAddr as string for the ping destination.
    Accepts timeout in ms for the ping timeout.
    Returns True if ping succeeds otherwise Returns False.
        Ping succeeds if it returns 0 and the output includes b'TTL='
    '''
    if platform.system().lower() == 'windows':
        numFlag = '-n'
    else:
        numFlag = '-c'
    completedPing = subprocess.run(['ping', numFlag, '1', '-w', str(timeout), ipAddr],
                                   stdout=subprocess.PIPE,    # Capture standard out
                                   stderr=subprocess.STDOUT)  # Capture standard error
    # print(completedPing.stdout)
    return (completedPing.returncode == 0) and (b'TTL=' in completedPing.stdout)

print(ping('google.com'))

Remarque: Cela capture la sortie au lieu de l'imprimer, donc si vous voulez voir la sortie de ping, vous devrez imprimer completedPing.stdoutavant de revenir.

Brent Robertson
la source
0

WINDOWS UNIQUEMENT - Je ne peux pas croire que personne ne s'est ouvert Win32_PingStatus En utilisant une simple requête WMI, nous renvoyons un objet rempli d'informations très détaillées gratuitement

import wmi


# new WMI object
c = wmi.WMI()

# here is where the ping actually is triggered
x = c.Win32_PingStatus(Address='google.com')

# how big is this thing? - 1 element
print 'length x: ' ,len(x)


#lets look at the object 'WMI Object:\n'
print x


#print out the whole returned object
# only x[0] element has values in it
print '\nPrint Whole Object - can directly reference the field names:\n'
for i in x:
    print i



#just a single field in the object - Method 1
print 'Method 1 ( i is actually x[0] ) :'
for i in x:
    print 'Response:\t', i.ResponseTime, 'ms'
    print 'TTL:\t', i.TimeToLive


#or better yet directly access the field you want
print '\npinged ', x[0].ProtocolAddress, ' and got reply in ', x[0].ResponseTime, 'ms'

sortie d'échantillon

Aimondy
la source
0

Mon emprunt à d'autres réponses. Essayez de simplifier et de minimiser les requêtes.

import platform, os

def ping(host):
    result = os.popen(' '.join(("ping", ping.param, host))).read()
    return 'TTL=' in result

ping.param = "-n 1" if platform.system().lower() == "windows" else "-c 1"
misantroop
la source
0

J'avais besoin d'un balayage de ping plus rapide et je ne voulais pas utiliser de bibliothèques externes, j'ai donc résolu d'utiliser la concurrence en utilisant intégré asyncio .

Ce code nécessite python 3.7+ et est fabriqué et testé sous Linux uniquement . Cela ne fonctionnera pas sous Windows, mais je suis sûr que vous pouvez facilement le modifier pour qu'il fonctionne sur Windows.

Je ne suis pas un expert avec asynciomais j'ai utilisé cet excellent article Accélérez votre programme Python avec la concurrence et j'ai proposé ces lignes de codes. J'ai essayé de le rendre aussi simple que possible, vous devrez donc probablement y ajouter plus de code pour répondre à vos besoins.

Il ne renvoie ni vrai ni faux, j'ai pensé qu'il serait plus pratique de lui faire imprimer l'adresse IP qui répond à une demande de ping. Je pense que c'est assez rapide, avec un ping de 255 ips en près de 10 secondes.

#!/usr/bin/python3

import asyncio

async def ping(host):
    """
    Prints the hosts that respond to ping request
    """
    ping_process = await asyncio.create_subprocess_shell("ping -c 1 " + host + " > /dev/null 2>&1")
    await ping_process.wait()

    if ping_process.returncode == 0:
        print(host)
    return 


async def ping_all():
    tasks = []

    for i in range(1,255):
        ip = "192.168.1.{}".format(i)
        task = asyncio.ensure_future(ping(ip))
        tasks.append(task)

    await asyncio.gather(*tasks, return_exceptions = True)

asyncio.run(ping_all())

Exemple de sortie:

192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6

Notez que les adresses IP ne sont pas dans l'ordre, car l'adresse IP est imprimée dès qu'elle répond, donc celle qui répond en premier est imprimée en premier.

Ahmed Essam
la source
-3
  1 #!/usr/bin/python
  2
  3 import os
  4 import sys
  5 import time
  6
  7 os.system("clear")
  8 home_network = "172.16.23."
  9 mine = []
 10
 11 for i in range(1, 256):
 12         z =  home_network + str(i)
 13         result = os.system("ping -c 1 "+ str(z))
 14         os.system("clear")
 15         if result == 0:
 16                 mine.append(z)
 17
 18 for j in mine:
 19         print "host ", j ," is up"

Un simple que je viens de préparer en une minute ... en utilisant icmplib, il faut des privilèges root, le ci-dessous fonctionne plutôt bien! HTH

utilisateur3423128
la source