Ping-Server in Python

167

Gibt es in Python eine Möglichkeit, einen Server über ICMP zu pingen und TRUE zurückzugeben, wenn der Server antwortet, oder FALSE, wenn keine Antwort erfolgt?

Kudu
quelle
1
Verwandte: Ping eine Site in Python?
JFS

Antworten:

111

Diese Funktion funktioniert unter jedem Betriebssystem (Unix, Linux, MacOS und Windows)
Python 2 und Python 3

EDITS:
By @radato os.system wurde ersetzt durch subprocess.call. Dies vermeidet die Sicherheitsanfälligkeit durch Shell-Injection in Fällen, in denen Ihre Hostnamen-Zeichenfolge möglicherweise nicht überprüft wird.

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

Beachten Sie, dass diese Funktion laut @ikrase unter Windows immer noch zurückgegeben wird, Truewenn Sie eine Destination Host UnreachableFehlermeldung erhalten.

Erläuterung

Der Befehl ist pingsowohl in Windows- als auch in Unix-ähnlichen Systemen verfügbar.
Die Option -n(Windows) oder -c(Unix) steuert die Anzahl der Pakete, die in diesem Beispiel auf 1 gesetzt wurden.

platform.system()Gibt den Plattformnamen zurück. Ex. 'Darwin'unter macOS.
subprocess.call()führt einen Systemaufruf durch. Ex. subprocess.call(['ls','-l']).

ePi272314
quelle
14
Beachten Sie, dass dies (unter Windows) immer noch true zurückgibt, wenn Sie von einem anderen Host die Antwort "Zielhost nicht erreichbar" erhalten.
ikrase
Ich stelle fest, dass ich gelegentlich einen Ping-Erfolg bekomme, wenn mein Modem ausgeschaltet ist ??? Damit werden "8.8.8.8" und "google.com" unter einem Windows 10-Betriebssystem getestet. Etwas stimmt nicht ganz.
Markus
Das kann bei Markus nicht passieren. Bitte testen Sie von Hand und mit einer modifizierten Version des obigen Codes und teilen Sie uns das Ergebnis mit. Von Hand: 1) cmd öffnen 2) ping 8.8.8.8 -n 13) echo %ERRORLEVEL%. Code: Ändern Sie die letzte Zeile des Python-Codes in return system_call(command). Bei richtiger Konnektivität erhalten Sie 0 (Null). Bei ausgeschaltetem Modem müssen Sie einen Fehlercode erhalten. Natürlich müssen beide Methoden unter denselben Bedingungen denselben Fehlercode zurückgeben.
ePi272314
Es ist passiert und ich habe den genauen Code Wort für Wort verwendet. Ich verstehe und glaube Ihren Kommentaren, dass ein Befehlszeilen-Ping auf keinen Fall erfolgreich sein kann, wenn keine Verbindung besteht. Daher dachte ich, dass etwas in der Python-Befehlszeilenoperation nicht richtig funktioniert. Ich werde das Update ausprobieren und sehen, wie es geht. Vielen Dank.
Markus
@ Markus siehe ikrases Kommentar.
Boris
163

Wenn Sie Windows nicht unterstützen müssen, finden Sie hier eine sehr übersichtliche Möglichkeit:

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!'

Dies funktioniert, weil ping einen Wert ungleich Null zurückgibt, wenn die Verbindung fehlschlägt. (Der Rückgabewert unterscheidet sich je nach Netzwerkfehler.) Sie können das Ping-Timeout (in Sekunden) auch mit der Option '-t' ändern. Beachten Sie, dass dadurch Text an die Konsole ausgegeben wird.

10flow
quelle
42
Ich endete mit dieser Varianteresponse = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
MGP
4
@ jeckyll2hide man ping, sende nur 1 Paket mit einer Frist von 2 Sekunden und leite alle Ausgaben nach / dev / null um, rufe nur den Rückgabewert ab.
MGP
@ ManuelGutierrez Ich denke, Sie wollen "-W 2000" (Timeout nach 2000 Millisekunden) und vielleicht "-t 3" (Exit nach 3 Sekunden, egal was
passiert
1
-w und -W nehmen Werte in Sekunden und nicht in Millisekunden an. Überprüfen Sie man ping, um sicherzugehen.
Alan Turing
7
Wenn Sie die hostnameZeichenfolge von einem Benutzer erhalten, kann dieser Ihren Server leicht hacken, indem er Ihnen eine "URL" wie "Gefällt mir" gibt 'google.com; rm -rf /*'. Verwenden Sie subprocess.run(["ping", "-c", "1", hostname]).returncodestattdessen.
Boris
38

Es gibt ein Modul namens Pyping , das dies tun kann. Es kann mit pip installiert werden

pip install pyping

Die Verwendung dieses Moduls ist recht einfach. Wenn Sie dieses Modul verwenden, benötigen Sie jedoch Root-Zugriff, da unter der Haube Rohpakete erstellt werden.

import pyping

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

if r.ret_code == 0:
    print("Success")
else:
    print("Failed with {}".format(r.ret_code))
Stephen Cochran
quelle
4
"Beachten Sie, dass ICMP-Nachrichten nur von Prozessen gesendet werden können, die als Root ausgeführt werden (in Windows müssen Sie dieses Skript als 'Administrator' ausführen)."
Ben Hyde
1
Ich finde es gut, dass Sie das Zeitlimit und die Anzahl der gesendeten ICMP-Anforderungen angeben können. Ich konnte ein Skript schreiben, das alle Hosts im lokalen Subnetz erkennt. Die Ausführung erfolgt in 1 Sekunde anstelle von 255 Sekunden mit der os.system('ping -c 1 -t 1 hostname')Lösung. Außerdem ist die pypingBibliothek im Vergleich zur Verwendung der TCP / IP-Sockets-Bibliothek sehr einfach zu verwenden. Ich habe mein Ping-Programm mit beiden geschrieben und pypingist meiner Meinung nach viel schneller und einfacher zu verwenden, insbesondere wenn man mit der Verwendung der TCP / IP-Sockets-Bibliothek nicht vertraut ist.
MikeyE
10
funktioniert nicht mit py3. ModuleNotFoundError: Kein Modul mit dem Namen 'core'
alireza
2
Der 'Kern'-Fehler beruht auf einer Inkompatibilität mit Python3. Ich habe versucht, es für Python3 zu beheben, aber es sendet mir ständig Fehler. Die Github-Seite für Autoren und Projekte ist nicht verfügbar (404 nicht gefunden). wir müssen es selbst auf python3 portieren :-)
Andre
6
für python3 versuchen Sie 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
quelle
6
Das einzige Problem dabei ist, dass es unter Windows nicht funktionieren würde.
Kudu
8
Es sollte erwähnt werden, dass der Grund dafür so ist, dass ICMP root benötigt und / bin / ping dies umgeht, indem SUID gesetzt wird.
Catskul
1
Hinweis: Kann fehlschlagen, wenn sich der Ping an einem anderen Ort befindet. Verwenden Sie whereis ping, um den richtigen Pfad zu erhalten.
Oktober
4
Dies funktioniert unter Windows:ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Victor Lellis
1
Wie kann ich das Ergebnis analysieren, um zu überprüfen, ob die Antwort in Windows in Ordnung oder ko war?
Pitto
15

Für Python3 gibt es ein sehr einfaches und praktisches Python-Modul ping3 : ( pip install ping3benötigt Root- Rechte).

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

Dieses Modul ermöglicht auch die Anpassung einiger Parameter.

Александр Рублев
quelle
2
Für die Bearbeitung sind Root-Rechte erforderlich. Eine Diskussion zum Aufheben dieser Berechtigungen finden Sie hier: github.com/kyan001/ping3/issues/10
Dimitrios Mistriotis
1
Oh, brauche Root-Berechtigungen nicht nur für die Installation, sondern auch für die Ausführung: ping ("example.com")
Clock ZHONG
14

Da ich mein Python-Programm universell auf Version 2.7 und 3.x sowie auf der Plattform Linux, Mac OS und Windows haben möchte, musste ich die vorhandenen Beispiele ändern.

# 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
quelle
1
Anstelle von False if platform.system().lower()=="windows" else Truedir könnte man natürlich auch einfach verwenden platform.system().lower() != "windows".
Frerich Raabe
Nicht os.name!="nt"auch funktionieren? Zugegeben, ich habe es nicht bei allen Ver / Plattform-Combos ausprobiert!
Keeely
2
In meinem Fall gibt das Standard-Gateway eine 'nicht erreichbare' Nachricht zurück, aber der Windows-Ping-Befehl hat immer noch den Rückkehrcode 0. Dieser Ansatz hat also funktioniert (Entschuldigung für die Formatierung - seine 6 Zeilen, einschließlich der Funktionsdeklaration): 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 Sie möchten lieber 0 zurückgeben, wenn unreachablein der Pipe gefunden wird, nein?
Beeb
1
@beeb Ja, das habe ich auch getan, aber vergessen, den Kommentar zu aktualisieren. Meine aktuelle Funktion sieht wie folgt aus : pastebin.com/FEYWsVjK
wellspokenman
8

Nachdem ich mich umgesehen hatte, schrieb ich mein eigenes Ping-Modul, das eine große Anzahl von Adressen überwacht, asynchron ist und nicht viele Systemressourcen verbraucht. Sie finden es hier: https://github.com/romana/multi-ping/ Es ist Apache-lizenziert, sodass Sie es in Ihrem Projekt nach Belieben in Ihrem Projekt verwenden können.

Die Hauptgründe für die Implementierung meiner eigenen sind die Einschränkungen der anderen Ansätze:

  • Viele der hier genannten Lösungen erfordern eine Ausführung eines Befehlszeilenprogramms. Dies ist ziemlich ineffizient und ressourcenintensiv, wenn Sie eine große Anzahl von IP-Adressen überwachen müssen.
  • Andere erwähnen einige ältere Python-Ping-Module. Ich habe mir diese angesehen und am Ende hatten alle das eine oder andere Problem (z. B. das nicht korrekte Einstellen der Paket-IDs) und haben das Ping-Pingen einer großen Anzahl von Adressen nicht behandelt.
Jürgen Brendel
quelle
Netter Arbeitskollege! Wenn jemand es in Aktion sehen möchte, verwenden Sie einfach 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
quelle
Dieser Code hat möglicherweise die Antwort auf die Frage, aber es wäre hilfreich, einige Kommentare oder Erklärungen hinzuzufügen, wie Ihr Code das Problem löst.
skrrgwasme
5

Stellen Sie sicher, dass Pyping installiert ist, oder installieren Sie es. Pip Install Pyping

#!/usr/bin/python
import pyping

response = pyping.ping('Your IP')

if response.ret_code == 0:
    print("reachable")
else:
    print("unreachable")
Naveen
quelle
1
Vielen Dank! Ich muss diesen Code jedoch als root ausführen, damit er funktioniert.
Thomas
1
Pypings GitHub-Seite existiert nicht mehr und das PyPI-Paket wurde seit 2016 nicht aktualisiert.
Stevoisiak
Ich habe die folgenden Fehler erhalten: Import pyping Traceback (letzter Aufruf zuletzt): Datei "<stdin>", Zeile 1, in <module> File "/usr/local/lib/python3.6/dist-packages/pyping/__init__. py ", Zeile 3, in <Modul> vom Kernimport * ModuleNotFoundError: Kein Modul mit dem Namen 'core'
Clock ZHONG
5

Programmatisches ICMP-Ping ist aufgrund der erhöhten Berechtigungen, die zum Senden von ICMP-Rohpaketen erforderlich sind, kompliziert, und das Aufrufen von pingBinärdateien ist hässlich. Bei der Serverüberwachung können Sie dasselbe Ergebnis mit einer Technik namens TCP-Ping erzielen :

# 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

Intern wird dadurch einfach eine TCP-Verbindung zum Zielserver hergestellt und diese sofort getrennt, wobei die verstrichene Zeit gemessen wird. Diese spezielle Implementierung ist etwas eingeschränkt, da sie keine geschlossenen Ports verarbeitet, aber für Ihre eigenen Server ziemlich gut funktioniert.

Kravietz
quelle
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
quelle
3

Ich löse das mit:

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

Mit "TTL" können Sie feststellen, ob der Ping korrekt ist. Saludos

user3620655
quelle
3

Meine Reduktion unter Verwendung von Ideen aus Antworten in diesem Beitrag, aber nur unter Verwendung des neueren empfohlenen Unterprozessmoduls und von 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
quelle
1
Sie müssen nicht True if condition else Falsefür die Rückgabe von True oder False basierend auf einer Bedingung verwenden. Verwenden Sie einfach zB shell_needed = operating_sys == 'Windows'undreturn success == 0
emorris
2

Dieses Skript funktioniert unter Windows und sollte unter anderen Betriebssystemen funktionieren: Es funktioniert unter Windows, Debian und Macosx und benötigt einen Test unter 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
Matthew
quelle
Gute Antwort. Hier sind keine Administratorrechte für Windows erforderlich.
Bergsteiger
Ich erhalte so
Ja, das funktioniert definitiv nicht.
Gibt
2

Am Ende fand ich diese Frage in Bezug auf ein ähnliches Szenario. Ich habe das Pyping ausprobiert, aber das Beispiel von Naveen hat unter Windows 2.7 unter Windows nicht funktioniert.

Ein Beispiel, das für mich funktioniert hat, ist:

import pyping

response = pyping.send('Your IP')

if response['ret_code'] == 0:
    print("reachable")
else:
    print("unreachable")
Templer
quelle
1
pypingscheint kein Standardmodul zu sein. Vielleicht könnten Sie einen Link bereitstellen?
Mawg sagt, Monica am
2

Mit Multi-Ping ( pip install multiPing) habe ich diesen einfachen Code erstellt ( kopieren und einfügen, wenn Sie so wollen! ):

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

Verwendung:

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

Wenn Sie eine einzelne Probe wünschen, kann der zweite Parameter " 10" ignoriert werden!

Ich hoffe es hilft!

Geraldo Neto
quelle
4
tolle Bibliothek, aber brauche Root-Rechte.
Craynic Cai
2

Meine Version einer Ping-Funktion:

  • Funktioniert unter Python 3.5 und höher, unter Windows und Linux (sollte unter Mac funktionieren, kann es aber nicht testen).
  • Gibt unter Windows False zurück, wenn der Ping-Befehl mit "Destination Host Unreachable" fehlschlägt.
  • Und zeigt keine Ausgabe an, weder als Popup-Fenster noch in der Befehlszeile.
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

Fühlen Sie sich frei, es zu verwenden, wie Sie wollen.

Jose Francisco Lopez Pimentel
quelle
1

Scheint einfach genug, gab mir aber Anfälle. Ich bekam immer wieder "ICMP Open-Socket-Betrieb nicht erlaubt", sonst würden die Lösungen auflegen, wenn der Server offline wäre. Wenn Sie jedoch wissen möchten, dass der Server aktiv ist und Sie einen Webserver auf diesem Server ausführen, übernimmt curl die Aufgabe. Wenn Sie ssh und Zertifikate haben, reichen ssh und ein einfacher Befehl aus. Hier ist der 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
quelle
1

Ich hatte ähnliche Anforderungen, also habe ich sie wie unten gezeigt implementiert. Es wird unter Windows 64 Bit und Linux getestet.

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

Wenn IP nicht erreichbar ist, löst subprocess.check_output () eine Ausnahme aus. Eine zusätzliche Überprüfung kann durch Extrahieren von Informationen aus der Ausgabezeile 'Pakete: Gesendet = 2, Empfangen = 2, Verloren = 0 (0% Verlust)' erfolgen.

Luminos
quelle
1

Hier ist eine Lösung, die das Python- subprocessModul und das pingvom zugrunde liegenden Betriebssystem bereitgestellte CLI-Tool verwendet. Getestet unter Windows und Linux. Unterstützung beim Festlegen eines Netzwerkzeitlimits. Benötigt keine Root-Rechte (zumindest unter Windows und 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
quelle
0

Verwenden Sie dies, es wurde unter Python 2.7 getestet und funktioniert einwandfrei. Bei Erfolg wird die Ping-Zeit in Millisekunden zurückgegeben und bei Fehlschlag False zurückgegeben.

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
quelle
0

Eine Sache, die viele Antworten vermissen, ist, dass (zumindest in Windows) die ping Befehl 0 zurückgibt (was auf Erfolg hinweist), wenn er die Antwort "Zielhost nicht erreichbar" erhält.

Hier ist mein Code, der prüft, ob er b'TTL='in der Antwort enthalten ist, da dieser nur vorhanden ist, wenn der Ping den Host erreicht hat. Hinweis: Der größte Teil dieses Codes basiert auf den anderen Antworten hier.

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

Hinweis: Dadurch wird die Ausgabe erfasst, anstatt sie zu drucken. Wenn Sie also die Ausgabe von anzeigen möchten ping, müssen Sie completedPing.stdoutvor der Rückkehr drucken .

Brent Robertson
quelle
0

NUR WINDOWS - Ich kann nicht glauben, dass niemand Win32_PingStatus aufgerissen hat. Mit einer einfachen WMI-Abfrage geben wir ein Objekt mit wirklich detaillierten Informationen kostenlos zurück

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'

Beispielausgabe

Aimondy
quelle
0

Ich leihe mir andere Antworten aus. Versuchen Sie, Abfragen zu vereinfachen und zu minimieren.

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
quelle
0

Ich brauchte einen schnelleren Ping-Sweep und wollte keine externen Bibliotheken verwenden. Daher habe ich mich entschlossen, die Parallelität mithilfe der integrierten Bibliothek zu verwenden asyncio.

Dieser Code erfordert Python 3.7+ und wird nur unter Linux erstellt und getestet . Es funktioniert nicht unter Windows, aber ich bin sicher, dass Sie es leicht ändern können, um unter Windows zu funktionieren.

Ich bin kein Experte, asyncioaber ich habe diesen großartigen Artikel verwendet. Beschleunigen Sie Ihr Python-Programm mit Parallelität und mir diese Codezeilen ausgedacht. Ich habe versucht, es so einfach wie möglich zu gestalten. Daher müssen Sie höchstwahrscheinlich mehr Code hinzufügen, um Ihren Anforderungen zu entsprechen.

Es wird weder wahr noch falsch zurückgegeben. Ich dachte, es wäre bequemer, die IP-Adresse zu drucken, die auf eine Ping-Anfrage reagiert. Ich denke, es ist ziemlich schnell und pingt 255 ips in fast 10 Sekunden.

#!/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())

Beispielausgabe:

192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6

Beachten Sie, dass die IPs nicht in Ordnung sind, da die IP gedruckt wird, sobald sie antwortet, sodass die IP, die zuerst antwortet, zuerst gedruckt wird.

Ahmed Essam
quelle
-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"

Eine einfache, die ich gerade in einer Minute gekocht habe. Mit icmplib braucht man Root-Privilegien. Das Folgende funktioniert ziemlich gut! HTH

user3423128
quelle