HOWTO · Python

Python ping 服务器

本教程演示了如何在 Python 中 ping 服务器。

本页内容

要从 Python 检查主机是否会响应 ICMP 回显请求,可以通过 subprocess.call() 或 os.system() 调用操作系统的 ping 命令,也可以使用 ping3.ping() 函数。收到响应可以说明主机可达,并提供往返时间,但不能证明某个应用程序或服务可用。结果还取决于操作系统、已安装的工具、防火墙规则和网络策略。

在 Python 中使用 subprocess.call() 对服务器执行 ping

subprocess.call() 会运行程序并返回其进程退出状态。将命令作为列表传入,可以避免根据主机字符串拼接 shell 命令。用于指定数据包数量的选项因平台而异:常见的 ping 实现在 Windows 上使用 -n,在类 Unix 系统上使用 -c。

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

所提供运行环境中的观测输出如下。代码块中的输出文字保持英文原样:

ping is unavailable

如输出所示,所提供的运行环境中没有可用的 ping 命令。在安装了该命令的环境中运行此示例还需要网络访问。示例会隐藏命令输出:进程以状态码 0 退出时返回 True,以非零状态码退出时返回 False;程序不可用或超时时返回 None。非零状态码本身无法说明原因是丢包、过滤、名称解析失败,还是其他特定于系统的问题。请根据自己的环境调整主机地址和数据包数量选项。

在 Python 中使用 os.system() 对服务器执行 ping

os.system() 会通过 shell 运行命令字符串,并返回经过平台编码的状态。它没有 subprocess.call() 灵活;将未经信任的主机文本拼接进命令还可能导致 shell 注入。对于可能来自用户的值,优先使用 subprocess.call() 和参数列表。如果使用 os.system(),请指定固定且可信的主机,并根据当前平台选择数据包数量选项:

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

所提供运行环境中的观测输出如下。代码块中的输出文字保持英文原样:

ping is unavailable

如输出所示,所提供的运行环境中没有可用的 ping 命令。该命令可用时,此示例仍取决于本地 shell、ping 实现和网络状况。给可执行文件路径加引号可以处理路径中包含空格的情况,但 shell 命令字符串仍需谨慎处理;不要用任意用户输入替换 host。返回状态表示 shell 命令的结果,并不能说明 Web 服务器等服务是否正在接受连接。

在 Python 中使用 ping3.ping() 对服务器执行 ping

第三种方法是使用 ping3.ping() 函数发送 ICMP 回显请求,而不调用系统的 ping 命令。请在运行脚本所用的 Python 环境中通过 python -m pip install ping3 安装 ping3 包。根据操作系统和当前权限,发送 ICMP 数据包可能还需要额外权限。

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

所提供运行环境中的观测输出如下。代码块中的输出文字保持英文原样:

Install ping3 with: python -m pip install ping3

如输出所示,所提供的运行环境中未安装 ping3。安装后运行示例还需要适当的 ICMP 权限和网络访问。数值响应表示以秒为单位的往返时间。对于没有响应的情况,应结合已安装库的行为和当前环境来判断;不要假定它能区分主机不可达、数据包被过滤或数据包丢失。

如果需要安全地传递参数并使用系统已有的 ping 工具,可以选择 subprocess.call()。对于固定且可信的命令,os.system() 是较简短的 shell 调用方式。ping3.ping() 可以直接在 Python 中调用并返回计时信息,但需要额外安装软件包,也要考虑权限要求。以上三种方法测试的都是 ICMP 可达性;如果要确认特定服务是否正常工作,应使用应用层检查。