HOWTO · Python
Python ping 伺服器
本教程演示瞭如何在 Python 中 ping 伺服器。
本頁內容
若要從 Python 檢查主機是否會回應 ICMP echo request,可以透過 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 injection。對於可能來自使用者的值,建議使用 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 命令的結果,不能說明像網頁伺服器這類服務是否正在接受連線。
在 Python 中使用 ping3.ping() 對伺服器執行 ping
第三種方式是使用 ping3.ping() 函式。它會傳送 ICMP echo request,而不呼叫系統的 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 可達性;若要確認特定服務是否正常運作,請改用應用程式層級的檢查。