HOWTO · Python

Python Ping

Questo tutorial mostra come eseguire il ping di un server in Python

In questa pagina

Per verificare da Python se un host risponde alle richieste ICMP Echo, puoi eseguire il comando ping del sistema operativo con subprocess.call() o os.system(), oppure usare la funzione ping3.ping(). Una risposta può indicare che l’host è raggiungibile e fornire il tempo di andata e ritorno, ma non dimostra che una specifica applicazione o un servizio siano disponibili. I risultati dipendono anche dal sistema operativo, dagli strumenti installati, dalle regole del firewall e dai criteri di rete.

Eseguire il ping di un server in Python con subprocess.call()

subprocess.call() esegue un programma e restituisce il suo codice di uscita. Passare il comando come elenco evita di costruire un comando shell concatenando il testo dell’host. L’opzione per il numero di pacchetti varia a seconda della piattaforma: nelle implementazioni comuni di ping si usa -n su Windows e -c sui sistemi Unix-like.

import platform
import shutil
import subprocess


def ping_host(host):
    ping = shutil.which("ping")
    if ping is None:
        return None  # The ping program is not installed or on PATH.

    count_option = "-n" if platform.system() == "Windows" else "-c"
    try:
        status = subprocess.call(
            [ping, count_option, "1", host],
            stdout=subprocess.DEVNULL,
            stderr=subprocess.DEVNULL,
            timeout=5,
        )
    except (OSError, subprocess.TimeoutExpired):
        return None
    return status == 0


result = ping_host("example.com")
if result is None:
    print("ping is unavailable")
else:
    print("host responded" if result else "no successful response")

Output osservato nell’ambiente di esecuzione fornito:

ping is unavailable

Come mostra l’output fornito, nell’ambiente di esecuzione ping non era disponibile. Se il comando è installato, questo esempio richiede anche l’accesso alla rete. L’esempio non mostra l’output del comando e restituisce True se il processo termina con codice zero, False per un codice diverso da zero oppure None se il programma non è disponibile o viene raggiunto il timeout. Un codice diverso da zero non permette di stabilire se la causa sia la perdita di pacchetti, un filtro, la risoluzione dei nomi o un’altra condizione specifica del sistema. Adatta l’host e l’opzione per il numero di pacchetti al tuo ambiente. L’etichetta leggibile presente nel blocco di output invariato resta in inglese.

Eseguire il ping di un server in Python con os.system()

os.system() esegue una stringa di comando tramite una shell e restituisce uno stato codificato in base alla piattaforma. È meno flessibile di subprocess.call() e concatenare testo non attendibile dell’host al comando può consentire un’iniezione di comandi nella shell. Per i valori che possono provenire dagli utenti, preferisci passare un elenco di argomenti a subprocess.call(). Se usi os.system() con un host fisso e attendibile, scegli l’opzione per il numero di pacchetti adatta alla piattaforma corrente:

import os
import platform
import shutil

host = "example.com"  # Keep this fixed or validate it before use.
ping = shutil.which("ping")
if ping is None:
    print("ping is unavailable")
else:
    count_option = "-n" if platform.system() == "Windows" else "-c"
    status = os.system(f'"{ping}" {count_option} 1 {host} > "{os.devnull}" 2>&1')
    print("host responded" if status == 0 else "no successful response")

Output osservato nell’ambiente di esecuzione fornito:

ping is unavailable

Come mostra l’output fornito, nell’ambiente di esecuzione ping non era disponibile. Quando è presente, questo esempio dipende dalla shell locale, dall’implementazione di ping e dalla rete. Racchiudere tra virgolette il percorso dell’eseguibile gestisce gli spazi nel percorso, ma le stringhe di comando per la shell richiedono comunque attenzione: non sostituire host con input arbitrario fornito dall’utente. Lo stato indica il risultato del comando eseguito dalla shell, non se un servizio, come un server web, accetta connessioni. L’etichetta leggibile presente nel blocco di output invariato resta in inglese.

Eseguire il ping di un server in Python con ping3.ping()

La terza opzione è la funzione ping3.ping(), che invia una richiesta ICMP Echo senza avviare il comando di sistema ping. Installa il pacchetto ping3 nell’ambiente Python usato dallo script con python -m pip install ping3. A seconda del sistema operativo e dei privilegi, per inviare pacchetti ICMP potrebbero servire autorizzazioni aggiuntive.

try:
    from ping3 import ping
except ImportError:
    print("Install ping3 with: python -m pip install ping3")
else:
    host = "example.com"
    response = ping(host)
    if response is None or response is False:
        print("no response reported")
    else:
        print(f"round-trip time: {response} seconds")

Output osservato nell’ambiente di esecuzione fornito:

Install ping3 with: python -m pip install ping3

Come mostra l’output fornito, nell’ambiente di esecuzione ping3 non era installato. Dopo averlo installato, l’esempio richiede anche autorizzazioni ICMP adeguate e accesso alla rete. Una risposta numerica rappresenta il tempo di andata e ritorno in secondi. Interpreta l’assenza di una risposta in base al comportamento della libreria installata e dell’ambiente; non presumere che distingua un host irraggiungibile da pacchetti filtrati o persi. L’etichetta leggibile presente nel blocco di output invariato resta in inglese.

Scegli subprocess.call() se vuoi passare gli argomenti in modo sicuro e usare l’utility ping già disponibile nel sistema. os.system() è un’opzione più breve basata sulla shell, adatta a un comando fisso e attendibile. ping3.ping() esegue la chiamata in Python e può restituire informazioni sui tempi, ma richiede un pacchetto aggiuntivo e può comportare requisiti di autorizzazione. In tutti e tre i casi, il ping verifica soltanto la raggiungibilità ICMP: se vuoi sapere se un servizio specifico funziona, esegui un controllo a livello applicativo.