Answers:
此功能可在任何操作系统(Unix,Linux,macOS和Windows)
Python 2和Python 3中使用
编辑:
被@radato os.system
替换为subprocess.call
。这样可以避免在主机名字符串可能未经验证的情况下出现外壳注入漏洞。
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
请注意,根据Windows上的@ikrase,True
如果遇到Destination Host Unreachable
错误,此函数仍将返回。
说明
该命令ping
在Windows和类似Unix的系统中都可以使用。
选项-n
(Windows)或-c
(Unix)控制在此示例中设置为1的数据包数。
platform.system()
返回平台名称。例如 'Darwin'
在macOS上。
subprocess.call()
执行系统调用。例如 subprocess.call(['ls','-l'])
。
ping 8.8.8.8 -n 1
3)echo %ERRORLEVEL%
。代码:将Python代码的最后一行修改为return system_call(command)
。有了正确的连接,您将得到0(零)。关闭调制解调器后,您必须获取一些错误代码。当然,这两种方法必须在相同条件下返回相同的错误代码。
如果您不需要支持Windows,这是一种非常简洁的方法:
import os
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)
#and then check the response...
if response == 0:
print hostname, 'is up!'
else:
print hostname, 'is down!'
之所以有效,是因为如果连接失败,ping将返回非零值。(返回值实际上取决于网络错误。)您还可以使用'-t'选项更改ping超时(以秒为单位)。注意,这会将文本输出到控制台。
response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
man ping
以确保。
hostname
从用户那里获得字符串,他们可以通过给您一个类似的“ url”来轻松地入侵您的服务器'google.com; rm -rf /*'
。使用subprocess.run(["ping", "-c", "1", hostname]).returncode
代替。
有一个叫做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))
os.system('ping -c 1 -t 1 hostname')
解决方案,它将在1秒内执行,而不是255秒。pyping
与使用TCP / IP套接字库相比,该库非常易于使用。我认为我pyping
是同时使用这两种方法编写ping程序的,并且据我所知,它更快捷,更容易使用,尤其是在不熟悉使用TCP / IP套接字库的情况下。
pip install ping3
import subprocess
ping_response = subprocess.Popen(["/bin/ping", "-c1", "-w100", "192.168.0.1"], stdout=subprocess.PIPE).stdout.read()
whereis ping
以获得正确的路径。
ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
对于python3,有一个非常简单方便的python模块ping3:(pip install ping3
,需要root特权)。
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
该模块还允许自定义一些参数。
因为我希望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"))
False if platform.system().lower()=="windows" else True
当然,也可以使用代替您platform.system().lower() != "windows"
。
os.name!="nt"
还工作吗?诚然,我还没有在所有ver / platform组合上尝试过它!
def 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
unreachable
在管道中找到,您宁愿返回0 ,不是吗?
环顾四周后,我最终编写了自己的ping模块,该模块旨在监视大量地址,是异步的并且不占用大量系统资源。您可以在这里找到它:https : //github.com/romana/multi-ping/它是Apache许可的,因此您可以按照自己认为合适的任何方式在项目中使用它。
实施我自己的主要原因是其他方法的局限性:
#!/usr/bin/python3
import subprocess as sp
def ipcheck():
status,result = sp.getstatusoutput("ping -c1 -w2 " + str(pop))
if status == 0:
print("System " + str(pop) + " is UP !")
else:
print("System " + str(pop) + " is DOWN !")
pop = input("Enter the ip address: ")
ipcheck()
确保已安装pyping或将其安装pip install pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
由于发送原始ICMP数据包需要提升的特权,因此编程ICMP ping变得很复杂,并且调用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连接并立即将其断开,从而测量经过的时间。这种特定的实现方式有一点局限性,因为它不能处理封闭的端口,但是对于您自己的服务器来说,它可以很好地工作。
我减少了使用本文中答案的想法,但仅使用推荐的更新子过程模块和python3:
import subprocess
import platform
operating_sys = platform.system()
nas = '192.168.0.10'
def ping(ip):
# ping_command = ['ping', ip, '-n', '1'] instead of ping_command = ['ping', ip, '-n 1'] for Windows
ping_command = ['ping', ip, '-n', '1'] if operating_sys == 'Windows' else ['ping', ip, '-c 1']
shell_needed = True if operating_sys == 'Windows' else False
ping_output = subprocess.run(ping_command,shell=shell_needed,stdout=subprocess.PIPE)
success = ping_output.returncode
return True if success == 0 else False
out = ping(nas)
print(out)
True if condition else False
根据条件返回True或False。只需使用eg shell_needed = operating_sys == 'Windows'
和return success == 0
该脚本可在Windows上运行,并且应可在其他操作系统上运行:它可在Windows,Debian和macosx上运行,需要在solaris上进行测试。
import os
import platform
def isUp(hostname):
giveFeedback = False
if platform.system() == "Windows":
response = os.system("ping "+hostname+" -n 1")
else:
response = os.system("ping -c 1 " + hostname)
isUpBool = False
if response == 0:
if giveFeedback:
print hostname, 'is up!'
isUpBool = True
else:
if giveFeedback:
print hostname, 'is down!'
return isUpBool
print(isUp("example.com")) #Example domain
print(isUp("localhost")) #Your computer
print(isUp("invalid.example.com")) #Unresolvable hostname: https://tools.ietf.org/html/rfc6761
print(isUp("192.168.1.1")) #Pings local router
print(isUp("192.168.1.135")) #Pings a local computer - will differ for your network
我最终发现了关于类似情况的这个问题。我尝试了pyping,但是Naveen给出的示例在Windows的Python 2.7下不起作用。
一个对我有用的例子是:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
pyping
似乎不是标准模块。也许您可以提供一个链接?
使用Multi-ping(pip install multiPing
),我编写了以下简单代码(如果需要,只需复制并粘贴!):
from multiping import MultiPing
def ping(host,n = 0):
if(n>0):
avg = 0
for i in range (n):
avg += ping(host)
avg = avg/n
# Create a MultiPing object to test hosts / addresses
mp = MultiPing([host])
# Send the pings to those addresses
mp.send()
# With a 1 second timout, wait for responses (may return sooner if all
# results are received).
responses, no_responses = mp.receive(1)
for addr, rtt in responses.items():
RTT = rtt
if no_responses:
# Sending pings once more, but just to those addresses that have not
# responded, yet.
mp.send()
responses, no_responses = mp.receive(1)
RTT = -1
return RTT
用法:
#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)
如果只需要一个样本,10
则可以忽略第二个参数“ ”!
希望能帮助到你!
我的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 (Mac not tested, should work)
'''
# 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
随时随地使用它。
看起来很简单,但是很适合我。我一直收到“不允许icmp打开套接字操作”的信息,否则如果服务器脱机,解决方案将挂断。但是,如果您想知道服务器仍在运行并且您正在该服务器上运行Web服务器,那么curl将完成这项工作。如果您拥有ssh和证书,那么ssh和一个简单的命令就足够了。这是代码:
from easyprocess import EasyProcess # as root: pip install EasyProcess
def ping(ip):
ping="ssh %s date;exit"%(ip) # test ssh alive or
ping="curl -IL %s"%(ip) # test if http alive
response=len(EasyProcess(ping).call(timeout=2).stdout)
return response #integer 0 if no response in 2 seconds
我有类似的要求,所以我如下所示实现了它。已在Windows 64位和Linux上进行了测试。
import subprocess
def systemCommand(Command):
Output = ""
Error = ""
try:
Output = subprocess.check_output(Command,stderr = subprocess.STDOUT,shell='True')
except subprocess.CalledProcessError as e:
#Invalid command raises this exception
Error = e.output
if Output:
Stdout = Output.split("\n")
else:
Stdout = []
if Error:
Stderr = Error.split("\n")
else:
Stderr = []
return (Stdout,Stderr)
#in main
Host = "ip to ping"
NoOfPackets = 2
Timeout = 5000 #in milliseconds
#Command for windows
Command = 'ping -n {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
#Command for linux
#Command = 'ping -c {0} -w {1} {2}'.format(NoOfPackets,Timeout,Host)
Stdout,Stderr = systemCommand(Command)
if Stdout:
print("Host [{}] is reachable.".format(Host))
else:
print("Host [{}] is unreachable.".format(Host))
当IP不可访问时,subprocess.check_output()引发异常。可以通过从输出行“数据包:已发送= 2,已接收= 2,丢失= 0(丢失0%)”中提取信息来进行额外的验证。
这是使用Python subprocess
模块和ping
底层操作系统提供的CLI工具的解决方案。在Windows和Linux上测试。支持设置网络超时。不需要root特权(至少在Windows和Linux上)。
import platform
import subprocess
def ping(host, network_timeout=3):
"""Send a ping packet to the specified host, using the system "ping" command."""
args = [
'ping'
]
platform_os = platform.system().lower()
if platform_os == 'windows':
args.extend(['-n', '1'])
args.extend(['-w', str(network_timeout * 1000)])
elif platform_os in ('linux', 'darwin'):
args.extend(['-c', '1'])
args.extend(['-W', str(network_timeout)])
else:
raise NotImplemented('Unsupported OS: {}'.format(platform_os))
args.append(host)
try:
if platform_os == 'windows':
output = subprocess.run(args, check=True, universal_newlines=True).stdout
if output and 'TTL' not in output:
return False
else:
subprocess.run(args, check=True)
return True
except (subprocess.CalledProcessError, subprocess.TimeoutExpired):
return False
使用它,它已经在python 2.7上进行了测试,并且工作正常,如果成功返回ping时间(以毫秒为单位),失败则返回False。
import platform,subproccess,re
def Ping(hostname,timeout):
if platform.system() == "Windows":
command="ping "+hostname+" -n 1 -w "+str(timeout*1000)
else:
command="ping -i "+str(timeout)+" -c 1 " + hostname
proccess = subprocess.Popen(command, stdout=subprocess.PIPE)
matches=re.match('.*time=([0-9]+)ms.*', proccess.stdout.read(),re.DOTALL)
if matches:
return matches.group(1)
else:
return False
许多答案遗漏的一件事是(至少在Windows中) ping
命令如果收到答复“目标主机不可达”,则返回0(表示成功)。
这是我的代码,用于检查b'TTL='
响应中是否存在,因为仅当ping到达主机时才存在。注意:大部分代码基于此处的其他答案。
import platform
import subprocess
def ping(ipAddr, timeout=100):
'''
Send a ping packet to the specified host, using the system ping command.
Accepts ipAddr as string for the ping destination.
Accepts timeout in ms for the ping timeout.
Returns True if ping succeeds otherwise Returns False.
Ping succeeds if it returns 0 and the output includes b'TTL='
'''
if platform.system().lower() == 'windows':
numFlag = '-n'
else:
numFlag = '-c'
completedPing = subprocess.run(['ping', numFlag, '1', '-w', str(timeout), ipAddr],
stdout=subprocess.PIPE, # Capture standard out
stderr=subprocess.STDOUT) # Capture standard error
# print(completedPing.stdout)
return (completedPing.returncode == 0) and (b'TTL=' in completedPing.stdout)
print(ping('google.com'))
注意:这是捕获输出而不是打印输出,因此,如果要查看的输出ping
,则需要completedPing.stdout
在返回之前进行打印。
仅限WINDOWS-无法相信没有人能破解Win32_PingStatus使用简单的WMI查询,我们免费返回了一个包含非常详细的信息的对象
import wmi
# new WMI object
c = wmi.WMI()
# here is where the ping actually is triggered
x = c.Win32_PingStatus(Address='google.com')
# how big is this thing? - 1 element
print 'length x: ' ,len(x)
#lets look at the object 'WMI Object:\n'
print x
#print out the whole returned object
# only x[0] element has values in it
print '\nPrint Whole Object - can directly reference the field names:\n'
for i in x:
print i
#just a single field in the object - Method 1
print 'Method 1 ( i is actually x[0] ) :'
for i in x:
print 'Response:\t', i.ResponseTime, 'ms'
print 'TTL:\t', i.TimeToLive
#or better yet directly access the field you want
print '\npinged ', x[0].ProtocolAddress, ' and got reply in ', x[0].ResponseTime, 'ms'
我需要更快的ping扫描,并且我不想使用任何外部库,所以我决定使用内置的并发性asyncio
。
此代码需要python 3.7+,并且仅在Linux上进行制作和测试。它在Windows上不起作用,但是我相信您可以轻松地将其更改为在Windows上工作。
我不是专家,asyncio
但是我使用了这篇很棒的文章“使用并发加速Python程序”,我想到了这些代码行。我试图使其尽可能地简单,因此很可能需要向其添加更多代码以满足您的需求。
它不会返回true或false,我认为将它打印出响应ping请求的IP会更方便。我认为这非常快,在将近10秒内ping 255 ips 。
#!/usr/bin/python3
import asyncio
async def ping(host):
"""
Prints the hosts that respond to ping request
"""
ping_process = await asyncio.create_subprocess_shell("ping -c 1 " + host + " > /dev/null 2>&1")
await ping_process.wait()
if ping_process.returncode == 0:
print(host)
return
async def ping_all():
tasks = []
for i in range(1,255):
ip = "192.168.1.{}".format(i)
task = asyncio.ensure_future(ping(ip))
tasks.append(task)
await asyncio.gather(*tasks, return_exceptions = True)
asyncio.run(ping_all())
样本输出:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
请注意,IP顺序不正确,因为IP会在答复时立即打印出来,因此首先响应的IP会首先打印出来。
1 #!/usr/bin/python
2
3 import os
4 import sys
5 import time
6
7 os.system("clear")
8 home_network = "172.16.23."
9 mine = []
10
11 for i in range(1, 256):
12 z = home_network + str(i)
13 result = os.system("ping -c 1 "+ str(z))
14 os.system("clear")
15 if result == 0:
16 mine.append(z)
17
18 for j in mine:
19 print "host ", j ," is up"
我在一分钟内就完成了一个简单的操作。使用icmplib需要root privs,下面的效果很好!高温超导