HOWTO · Python

Python Ping

Este tutorial demuestra cómo hacer ping a un servidor en Python

En esta página

Para comprobar desde Python si un host responde a solicitudes de eco ICMP, puedes llamar al comando ping del sistema operativo con subprocess.call() u os.system(), o usar la función ping3.ping(). Una respuesta puede indicar que el host es accesible y proporcionar el tiempo de ida y vuelta, pero no demuestra que una aplicación o un servicio concretos estén disponibles. Los resultados también dependen del sistema operativo, de las herramientas instaladas, de las reglas del cortafuegos y de las políticas de red.

Hacer ping a un servidor en Python con subprocess.call()

subprocess.call() ejecuta un programa y devuelve el estado de salida del proceso. Pasar el comando como una lista evita construir un comando de shell a partir de la cadena del host. La opción para indicar el número de paquetes varía según la plataforma: las implementaciones habituales de ping usan -n en Windows y -c en sistemas tipo Unix.

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

Salida observada en el entorno de ejecución proporcionado; las etiquetas del bloque de salida se mantienen en inglés:

ping is unavailable

Como muestra la salida, ping no estaba disponible en el entorno de ejecución proporcionado. Si está instalado, este ejemplo también necesita acceso a la red. Suprime la salida del comando y devuelve True si el proceso termina con estado cero, False si termina con un estado distinto de cero, o None si el programa no está disponible o se agota el tiempo de espera. Un estado distinto de cero no permite saber si la causa fue la pérdida de paquetes, un filtrado, la resolución de nombres u otra condición específica del sistema. Adapta el host y la opción del número de paquetes a tu entorno.

Hacer ping a un servidor en Python con os.system()

os.system() ejecuta una cadena de comando mediante un shell y devuelve un estado codificado según la plataforma. Es menos flexible que subprocess.call(), y concatenar texto de host que no sea de confianza en un comando puede permitir una inyección de shell. Para valores que podrían proceder de usuarios, es preferible pasar una lista de argumentos a subprocess.call(). Si usas os.system() con un host fijo y de confianza, elige la opción del número de paquetes adecuada para la plataforma actual:

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

Salida observada en el entorno de ejecución proporcionado; las etiquetas del bloque de salida se mantienen en inglés:

ping is unavailable

Como muestra la salida, ping no estaba disponible en el entorno de ejecución proporcionado. Si está disponible, este ejemplo depende del shell local, de la implementación de ping y de la red. Poner entre comillas la ruta del ejecutable permite manejar espacios en esa ruta, pero las cadenas de comandos para el shell siguen requiriendo cuidado; no sustituyas host por datos arbitrarios proporcionados por usuarios. El estado indica el resultado del comando ejecutado por el shell, no si un servicio como un servidor web acepta conexiones.

Hacer ping a un servidor en Python con ping3.ping()

La tercera opción es la función ping3.ping(), que envía una solicitud de eco ICMP sin invocar el comando ping del sistema. Instala el paquete ping3 en el entorno de Python que use tu script con python -m pip install ping3. Según el sistema operativo y los privilegios disponibles, enviar paquetes ICMP puede requerir permisos adicionales.

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

Salida observada en el entorno de ejecución proporcionado; las etiquetas del bloque de salida se mantienen en inglés:

Install ping3 with: python -m pip install ping3

Como muestra la salida, ping3 no estaba instalado en el entorno de ejecución proporcionado. Después de instalarlo, el ejemplo también requiere permisos adecuados para ICMP y acceso a la red. Una respuesta numérica representa el tiempo de ida y vuelta en segundos. Interpreta la ausencia de respuesta según el comportamiento de la biblioteca instalada y el entorno; no des por sentado que permite distinguir entre un host inaccesible y paquetes filtrados o perdidos.

Elige subprocess.call() si quieres pasar argumentos de forma segura y usar la utilidad ping del sistema. os.system() es una opción más breve basada en el shell para un comando fijo y de confianza. ping3.ping() permite hacer la llamada desde Python y puede devolver información sobre el tiempo, pero requiere un paquete adicional y puede plantear consideraciones de permisos. En los tres casos, ping solo comprueba la accesibilidad mediante ICMP; si necesitas saber si funciona un servicio concreto, haz una comprobación a nivel de aplicación.