如果您不需要支持Windows,这是一种非常简洁的方法:
import os
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)
#and then check the response...
if response == 0:
print(f"{hostname} is up!")
else:
print(f"{hostname} is down!")
response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
。 - MGPman ping
确认。 - Alan Turinghostname
字符串,他们可能会通过提供像 'google.com; rm -rf /*'
这样的 "url" 轻松地攻击您的服务器。请改用 subprocess.run(["ping", "-c", "1", hostname]).returncode
。 - user3064538subprocess.run
在 Python 3.6 中的解决方案:command = ["ping", "-c", "1", "-w2", host]
return subprocess.run(args=command, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode == 0
- Ian Colwell该函数适用于任何操作系统(Unix、Linux、macOS和Windows)
支持Python 2和Python 3
编辑:
由@radato替换了os.system
为subprocess.call
。这避免了在主机名字符串可能未经过验证的情况下出现shell注入漏洞。
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
请注意,根据@ikrase的说法,在Windows系统上,如果出现“目标主机不可达”错误,则此函数仍将返回True
。
说明
在Windows和类Unix系统中,命令都是ping
。
选项-n
(Windows)或-c
(Unix)控制数据包的数量,在本例中设置为1个。
platform.system()
返回平台名称。例如,在macOS上返回'Darwin'
。
subprocess.call()
执行系统调用。例如:subprocess.call(['ls', '-l'])
。
system.call
是个笔误,应该是 subprocess.call
的人? - ishahak有一个名为pyping的模块可以做到这一点。您可以使用pip进行安装。
pip install pyping
使用起来非常简单,但是当使用这个模块时,由于其在底层构建原始数据包,因此需要root访问权限。
import pyping
r = pyping.ping('google.com')
if r.ret_code == 0:
print("Success")
else:
print("Failed with {}".format(r.ret_code))
对于python3,有一个非常简单和方便的python模块ping3: (pip install ping3
,需要root权限)。
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
此模块还允许对一些参数进行自定义。
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
whereis ping
获取正确的路径。 - octernping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
。 - Victor Lellis在Python3中使用socket包:
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
由于发送原始ICMP数据包需要提升特权,而调用ping
二进制文件很不方便,因此编写程序化的ICMP ping是很复杂的。对于服务器监控,您可以使用一种称为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
在内部,这只是简单地建立与目标服务器的TCP连接并立即断开它,测量经过的时间。这个特定的实现有点局限性,因为它不能处理关闭的端口,但对于您自己的服务器来说,它运行得非常好。
因为我喜欢让我的Python程序适用于版本2.7和3.x以及Linux、Mac OS和Windows平台,所以我不得不修改现有的示例。
# 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"))
platform.system().lower() != "windows"
来替代 False if platform.system().lower()=="windows" else True
。 - Frerich Raabeos.name!="nt"
也可以工作吗?不过我还没有在所有版本/平台组合上尝试过! - Keeelydef ping(host): process = subprocess.Popen(["ping", "-n", "1",host], stdout=subprocess.PIPE, stderr=subprocess.PIPE) streamdata = process.communicate()[0] if 'unreachable' in str(streamdata): return 1 return process.returncode
- wombleroneunreachable
,你更愿意返回 0 吗? - beeb我的ping函数版本:
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
'''
# 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
随意使用,任何用途皆可。
在寻找了一番后,我最终编写了自己的ping模块,它旨在监控大量的地址,采用异步方式,并且不占用太多系统资源。您可以在这里找到它:https://github.com/romana/multi-ping/ 它是Apache许可证,因此您可以按照任何方式在项目中使用它。
实现自己的主要原因是其他方法的限制: