Servers pingen in Python

Is er in Python een manier om een server te pingen via ICMP en TRUE te retourneren als de server reageert, of FALSE als er geen reactie is?


Antwoord 1, autoriteit 100%

Deze functie werkt in elk besturingssysteem (Unix, Linux, macOS en Windows)
Python 2 en Python 3

BEWERKINGEN:
Door @radatoos.systemwerd vervangen door subprocess.call. Dit voorkomt een shell-injectie-kwetsbaarheid in gevallen waarin uw hostnaamreeks mogelijk niet wordt gevalideerd.

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

Houd er rekening mee dat, volgens @ikrase op Windows, deze functie nog steeds Trueretourneert als je een Destination Host Unreachable-fout krijgt.

Uitleg

De opdracht is pingin zowel Windows- als Unix-achtige systemen.
De optie -n(Windows) of -c(Unix) bepaalt het aantal pakketten dat in dit voorbeeld was ingesteld op 1.

platform.system()Retourneert de platformnaam. Ex. 'Darwin'OP MACOS.
subprocess.call()voert een systeem uit telefoongesprek. Ex. subprocess.call(['ls','-l']).


2, Autoriteit 121%

Als u geen Windows hoeft te ondersteunen, is hier een beknopte manier om het te doen:

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

Dit werkt omdat Ping een niet-nulwaarde retourneert als de verbinding mislukt. (De retourwaarde verschilt eigenlijk afhankelijk van de netwerkfout.) U kunt de pingtime-out (in seconden) ook wijzigen met behulp van de optie ‘-t’. Opmerking, dit wordt tekst naar de console uitgevoerd.


3, Autoriteit 31%

Er is een module genaamd pypen die dit kan doen. Het kan worden geïnstalleerd met PIP

pip install pyping

Het is echter vrij eenvoudig te gebruiken bij het gebruik van deze module, hebt u root-toegang nodig vanwege het feit dat het rauwe pakketten onder de motorkap is.

import pyping
r = pyping.ping('google.com')
if r.ret_code == 0:
    print("Success")
else:
    print("Failed with {}".format(r.ret_code))

4, Autoriteit 21%

import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()

5, Autoriteit 15%

Voor Python3 is er een zeer eenvoudige en handige Python-module ping3 : (pip install ping3, behoefte Root Privileges).

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

Met deze module kan de aanpassing van sommige parameters ook.


6, Autoriteit 11%

Omdat ik graag mijn Python-programma universeel heb op versie 2.7 en 3.x en op platform Linux, Mac OS en Windows, moest ik de bestaande voorbeelden wijzigen.

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

7, Autoriteit 10%

Programmatische ICMP-ping is ingewikkeld vanwege de verhoogde bevoegdheden die nodig zijn om onbewerkte ICMP-pakketten te verzenden, en het aanroepen van pingbinair is lelijk. Voor servermonitoring kunt u hetzelfde resultaat bereiken met een techniek genaamd TCP-ping:

# 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 wordt hiermee eenvoudig een TCP-verbinding met de doelserver tot stand gebracht en deze onmiddellijk verbroken, waarbij de verstreken tijd wordt gemeten. Deze specifieke implementatie is een beetje beperkt omdat het geen gesloten poorten aankan, maar voor je eigen servers werkt het redelijk goed.


Antwoord 8, autoriteit 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()

Antwoord 9, autoriteit 7%

Na wat rondkijken, heb ik uiteindelijk mijn eigen ping-module geschreven, die is ontworpen om grote aantallen adressen te bewaken, asynchroon is en niet veel systeembronnen gebruikt. Je kunt het hier vinden: https://github.com/romana/multi-ping/Het heeft een Apache-licentie, dus je kunt het in je project gebruiken op elke gewenste manier.

De belangrijkste redenen om de mijne te implementeren zijn de beperkingen van de andere benaderingen:

  • Veel van de hier genoemde oplossingen vereisen een uitvoer naar een opdrachtregelprogramma. Dit is vrij inefficiënt en verbruikt veel resources als u grote aantallen IP-adressen moet controleren.
  • Anderen noemen enkele oudere Python ping-modules. Ik heb die bekeken en uiteindelijk hadden ze allemaal een of ander probleem (zoals het niet correct instellen van pakket-ID’s) en konden ze het pingen van grote aantallen adressen niet aan.

Antwoord 10, autoriteit 5%

Zorg ervoor dat pyping is geïnstalleerd of installeer het pip install pyping

#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
    print("reachable")
else:
    print("unreachable")

Antwoord 11, autoriteit 4%

Mijn versie van een ping-functie:

  • Werkt op Python 3.5 en hoger, op Windows en Linux (zou moeten werken op Mac, maar kan het niet testen).
  • Retourneert in Windows False als de ping-opdracht mislukt met “Bestemmingshost onbereikbaar”.
  • En toont geen uitvoer, noch als pop-upvenster noch in de opdrachtregel.
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

Voel je vrij om het te gebruiken zoals je wilt.


Antwoord 12, autoriteit 3%

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

Antwoord 13, autoriteit 3%

Ik los dit op met:

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”is de manier om te weten of de ping correct is.
Saludos


Antwoord 14, autoriteit 3%

Mijn reductie met behulp van ideeën uit antwoorden in dit bericht, maar alleen met behulp van de nieuwere aanbevolen subprocesmodule en 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)

Antwoord 15, autoriteit 2%

Dit script werkt op Windows en zou op andere besturingssystemen moeten werken:
Het werkt op Windows, Debian en macosx, een test op solaris nodig.

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

Antwoord 16, autoriteit 2%

Uiteindelijk vond ik deze vraag over een soortgelijk scenario. Ik heb pyping geprobeerd, maar het voorbeeld van Naveen werkte niet voor mij in Windows onder Python 2.7.

Een voorbeeld dat voor mij werkte is:

import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
    print("reachable")
else:
    print("unreachable")

Antwoord 17, autoriteit 2%

Met behulp van Multi-ping(pip install multiPing) heb ik deze eenvoudige code gemaakt (gewoon kopiëren en plakken als je wilt!):

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

Gebruik:

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

Als u een enkel monster wilt, kan de tweede parameter “10” worden genegeerd!

Ik hoop dat het helpt!


Antwoord 18

Lijkt eenvoudig genoeg, maar gaf me krampen. Ik kreeg steeds “icmp open socket-bewerking niet toegestaan” of anders zouden de oplossingen ophangen als de server offline was. Als u echter wilt weten dat de server in leven is en u een webserver op die server gebruikt, zal curl het werk doen. Als je ssh en certificaten hebt, dan is ssh en een simpel commando voldoende. Hier is de 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

Antwoord 19

Ik had vergelijkbare vereisten, dus ik heb het geïmplementeerd zoals hieronder wordt weergegeven. Het is getest op Windows 64 bit en 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))

Wanneer IP is niet bereikbaar subprocess.check_output () werpt een uitzondering. Extra controle kan worden uitgevoerd door het extraheren van informatie uit uitgangslijn ‘Packets: verzonden = 2, ontvangen = 2, Lost = 0 (0% verlies)’

.


20

Hier is een oplossing met behulp van Python subprocessmodule en pingCLI tool van het onderliggende besturingssysteem. Getest op Windows en Linux. Ondersteuning van het instellen van een netwerk time-out. Hoeft niet root privileges (tenminste op Windows en 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

Antwoord 21

Gebruik dit, het is getest op python 2.7 en werkt prima, het retourneert de ping-tijd in milliseconden als het is gelukt en retourneert False bij falen.

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

Antwoord 22

ALLEEN WINDOWS – Ik kan niet geloven dat niemand Win32_PingStatus heeft geopend
Met behulp van een eenvoudige WMI-query retourneren we gratis een object vol met echt gedetailleerde informatie

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'

voorbeelduitvoer


Antwoord 23

Mijn mening is geleend van andere antwoorden. Poging om zoekopdrachten te vereenvoudigen en te minimaliseren.

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"

Antwoord 24

socketpakket gebruiken in python3:

import socket
def ping_server(server: str, port: int, timeout=3):
    """ping server"""
    try:
        socket.setdefaulttimeout(timeout)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((server, port))
    except OSError as error:
        return False
    else:
        s.close()
        return True

Antwoord 25

Ping ze allemaal in Windows of Linux, retourneer een gesorteerde lijst. Dit is een hybride/fix uit de reacties van @Ahmed Essam en @Arno.

import asyncio
import re
import platform
isWindows = platform.system()
async def ping(host):
    cmd = 'ping {} {} 1'.format(host, '-n' if isWindows else '-c')
    ping_proc = \
        await asyncio.create_subprocess_shell(cmd, stdout=asyncio.subprocess.PIPE,
                                                      stderr=asyncio.subprocess.PIPE)
    stdout, stderr = await ping_proc.communicate()
    outstr = stdout.decode()
    if ping_proc.returncode == 0:
        delay = int(re.search(r'(?:time=)([\d]*)', outstr).group(1)) if 'time=' in outstr else -1
        if delay >= 0:
            # print('{} {}ms'.format(host, delay))
            return [host, delay]
    return [host, None]
async def ping_all():
    tasks = []
    for i in range(1, 256):
        ip = "192.168.1.{}".format(i)
        task = asyncio.ensure_future(ping(ip))
        tasks.append(task)
    retList = await asyncio.gather(*tasks, return_exceptions=True)
    retList = [x for x in retList if x[1] is not None]
    retList.sort(key=lambda x: int(x[0].split('.')[-1]))
    return retList
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
pingRet = loop.run_until_complete(ping_all())
for ip, d in pingRet:
    print('{:<16s} {}ms'.format(ip, d))

26

Eén ding Veel van de antwoorden Miss is dat (althans in Windows) de pingOpdracht Returns 0 (aangeven) Als het het antwoord “Destination Host onbereikbaar ontvangt.”

Hier is mijn code die controleert of b'TTL='in het antwoord is, omdat dat alleen aanwezig is wanneer de ping de host bereikte. Opmerking: de meeste van deze code is gebaseerd op de andere antwoorden 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'))

Opmerking: dit legt de uitvoer vast in plaats van deze af te drukken, dus als u de uitvoer van pingwilt zien, moet u completedPing.stdoutafdrukken voordat u terugkeert .


Antwoord 27

 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"

Een simpele die ik zojuist in een minuut heb gemaakt.. met behulp van icmplib heb je root-privs nodig, het onderstaande werkt redelijk goed!
HTH

Other episodes