Câu trả lời:
Hàm này hoạt động trong mọi HĐH (Unix, Linux, macOS và Windows)
Python 2 và Python 3
EDITS :
Bởi @radato os.system
đã được thay thế bởi subprocess.call
. Điều này tránh tiêm vỏ lỗ hổng trong trường hợp chuỗi tên máy chủ của bạn có thể không được xác thực.
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
Lưu ý rằng, theo @ikrase trên Windows, chức năng này sẽ vẫn quay trở lại True
nếu bạn nhận đượcDestination Host Unreachable
lỗi.
Giải trình
Lệnh này có ping
trong cả hệ thống giống Windows và Unix.
Tùy chọn -n
(Windows) hoặc -c
(Unix) kiểm soát số lượng gói trong ví dụ này được đặt thành 1.
platform.system()
trả về tên nền tảng. Ví dụ. 'Darwin'
trên macOS.
subprocess.call()
thực hiện một cuộc gọi hệ thống. Ví dụ. subprocess.call(['ls','-l'])
.
ping 8.8.8.8 -n 1
3) echo %ERRORLEVEL%
. Mã: Sửa đổi dòng cuối cùng của mã Python thành return system_call(command)
. Với kết nối thích hợp, bạn sẽ nhận được 0 (không). Khi tắt modem, bạn phải nhận được một số mã lỗi. Tất nhiên, cả hai phương thức phải trả về cùng một mã lỗi trong cùng điều kiện.
Nếu bạn không cần hỗ trợ Windows, đây là một cách thực sự ngắn gọn để làm điều đó:
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!'
Điều này hoạt động vì ping trả về giá trị khác không nếu kết nối không thành công. (Giá trị trả về thực sự khác nhau tùy thuộc vào lỗi mạng.) Bạn cũng có thể thay đổi thời gian chờ ping (tính bằng giây) bằng tùy chọn '-t'. Lưu ý, điều này sẽ xuất văn bản đến bàn điều khiển.
response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
man ping
để đảm bảo.
hostname
chuỗi từ người dùng, họ có thể dễ dàng hack máy chủ của bạn bằng cách cho bạn một "url" như thế 'google.com; rm -rf /*'
. Sử dụng subprocess.run(["ping", "-c", "1", hostname]).returncode
thay thế.
Có một mô-đun gọi là pyping có thể làm điều này. Nó có thể được cài đặt với pip
pip install pyping
Nó khá đơn giản để sử dụng, tuy nhiên, khi sử dụng mô-đun này, bạn cần quyền truy cập root do thực tế là nó đang tạo ra các gói thô dưới mui xe.
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')
giải pháp. Ngoài ra, pyping
lib rất dễ sử dụng so với sử dụng thư viện socket TCP / IP. Tôi đã viết chương trình ping của mình bằng cả hai, và theo tôi, pyping
nhanh hơn và dễ sử dụng hơn, đặc biệt là nếu người ta không quen sử dụng thư viện socket 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
để có được đường dẫn chính xác.
ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Đối với python3, có một mô-đun python rất đơn giản và tiện lợi ping3 : ( pip install ping3
, cần quyền root ).
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
Mô-đun này cho phép tùy chỉnh một số tham số là tốt.
Vì tôi muốn chương trình Python của mình phổ biến trên phiên bản 2.7 và 3.x và trên nền tảng Linux, Mac OS và Windows, tôi đã phải sửa đổi các ví dụ hiện có.
# 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
bạn tất nhiên cũng có thể chỉ sử dụng platform.system().lower() != "windows"
.
os.name!="nt"
Nó cũng không hoạt động? Phải thừa nhận rằng tôi đã không thử nó trên tất cả các combo 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
được tìm thấy trong đường ống, phải không?
Sau khi nhìn xung quanh, cuối cùng tôi đã viết mô-đun ping của riêng mình, được thiết kế để giám sát số lượng lớn địa chỉ, không đồng bộ và không sử dụng nhiều tài nguyên hệ thống. Bạn có thể tìm thấy nó ở đây: https://github.com/romana/multi-ping/ Nó được cấp phép bởi Apache, vì vậy bạn có thể sử dụng nó trong dự án của mình theo bất kỳ cách nào bạn thấy phù hợp.
Những lý do chính để thực hiện của riêng tôi là những hạn chế của các phương pháp khác:
#!/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()
Đảm bảo pyping được cài đặt hoặc cài đặt nó pip cài đặt pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
Ping ICMP lập trình rất phức tạp do các đặc quyền nâng cao cần thiết để gửi các gói ICMP thô và việc gọi ping
nhị phân là xấu. Để giám sát máy chủ, bạn có thể đạt được kết quả tương tự bằng cách sử dụng kỹ thuật gọi là 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
Trong nội bộ, điều này chỉ đơn giản là thiết lập kết nối TCP đến máy chủ đích và loại bỏ nó ngay lập tức, đo thời gian trôi qua. Việc triển khai cụ thể này hơi hạn chế ở chỗ nó không xử lý các cổng đóng nhưng đối với các máy chủ của riêng bạn thì nó hoạt động khá tốt.
Tôi giải quyết điều này với:
def ping(self, host):
res = False
ping_param = "-n 1" if system_name().lower() == "windows" else "-c 1"
resultado = os.popen("ping " + ping_param + " " + host).read()
if "TTL=" in resultado:
res = True
return res
"TTL" là cách để biết ping có chính xác không. Saludos
Tôi giảm sử dụng ý tưởng từ các câu trả lời trong bài đăng này nhưng chỉ sử dụng mô-đun quy trình con được đề xuất mới hơn và 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
để trả về Đúng hoặc Sai dựa trên một điều kiện. Chỉ cần sử dụng ví dụ shell_needed = operating_sys == 'Windows'
vàreturn success == 0
Kịch bản này hoạt động trên Windows và nên hoạt động trên các HĐH khác: Nó hoạt động trên Windows, Debian và macosx, cần thử nghiệm trên 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
Tôi cuối cùng đã tìm thấy câu hỏi này liên quan đến một kịch bản tương tự. Tôi đã thử pyping nhưng ví dụ được đưa ra bởi Naveen không hoạt động với tôi trong Windows theo Python 2.7.
Một ví dụ làm việc cho tôi là:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
pyping
dường như không phải là một mô-đun tiêu chuẩn. Có lẽ bạn có thể cung cấp một liên kết?
Sử dụng Multi-ping ( pip install multiPing
) Tôi đã tạo mã đơn giản này ( chỉ cần sao chép và dán nếu bạn muốn! ):
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
Sử dụng:
#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)
Nếu bạn muốn một mẫu duy nhất, tham số thứ hai " 10
" có thể được bỏ qua!
Hy vọng nó giúp!
Phiên bản của tôi về chức năng 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
Hãy sử dụng nó như bạn muốn.
Có vẻ đủ đơn giản, nhưng đã cho tôi phù hợp. Tôi liên tục nhận được "icmp hoạt động ổ cắm mở không được phép" nếu không các giải pháp sẽ bị treo nếu máy chủ không hoạt động. Tuy nhiên, nếu điều bạn muốn biết là máy chủ còn sống và bạn đang chạy một máy chủ web trên máy chủ đó, thì curl sẽ thực hiện công việc. Nếu bạn có ssh và chứng chỉ, thì ssh và một lệnh đơn giản sẽ đủ. Đây là mã:
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
Tôi có yêu cầu tương tự vì vậy tôi đã thực hiện nó như hình dưới đây. Nó được thử nghiệm trên Windows 64 bit và 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))
Khi IP không thể truy cập được quy trình con.checkDefput () sẽ đưa ra một ngoại lệ. Có thể xác minh thêm bằng cách trích xuất thông tin từ dòng đầu ra 'Gói: Đã gửi = 2, Đã nhận = 2, Mất = 0 (mất 0%)'.
Đây là một giải pháp sử dụng subprocess
mô-đun của Python và ping
công cụ CLI được cung cấp bởi HĐH cơ bản. Đã thử nghiệm trên Windows và Linux. Hỗ trợ thiết lập thời gian chờ mạng. Không cần quyền root (ít nhất là trên Windows và 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
Sử dụng cái này, nó đã được thử nghiệm trên python 2.7 và hoạt động tốt, nó trả về thời gian ping tính bằng mili giây nếu thành công và trả về Sai khi thất bại.
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
Một điều mà rất nhiều câu trả lời bỏ lỡ là (ít nhất là trong Windows) ping
lệnh trả về 0 (biểu thị thành công) nếu nhận được câu trả lời "Máy chủ đích không thể truy cập được".
Đây là mã của tôi để kiểm tra xem b'TTL='
có trong phản hồi không, vì nó chỉ xuất hiện khi ping đến máy chủ. Lưu ý: Hầu hết các mã này được dựa trên các câu trả lời khác ở đây.
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'))
Lưu ý: Điều này ghi lại đầu ra thay vì in nó, vì vậy nếu bạn muốn xem đầu ra của ping
, bạn sẽ cần in completedPing.stdout
trước khi quay lại.
CHỈ WINDOWS - Không thể tin rằng không có ai bẻ khóa mở Win32_PingStatus Sử dụng truy vấn WMI đơn giản, chúng tôi trả lại một đối tượng có đầy đủ thông tin thực sự chi tiết
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'
Tôi cần quét ping nhanh hơn và tôi không muốn sử dụng bất kỳ thư viện bên ngoài nào, vì vậy tôi quyết định sử dụng đồng thời bằng cách sử dụng tích hợp asyncio
.
Mã này yêu cầu python 3.7+ và được tạo và thử nghiệm trên Linux . Nó sẽ không hoạt động trên Windows nhưng tôi chắc chắn bạn có thể dễ dàng thay đổi nó để hoạt động trên Windows.
Tôi không phải là chuyên gia asyncio
nhưng tôi đã sử dụng bài viết tuyệt vời này Tăng tốc chương trình Python của bạn với tính tương tranh và tôi đã đưa ra các dòng mã này. Tôi đã cố gắng làm cho nó đơn giản nhất có thể, vì vậy rất có thể bạn sẽ cần thêm nhiều mã hơn cho phù hợp với nhu cầu của bạn.
Nó không trả về đúng hay sai, tôi nghĩ sẽ thuận tiện hơn nếu chỉ in IP đáp ứng yêu cầu ping. Tôi nghĩ rằng nó khá nhanh, ping 255 ips trong gần 10 giây.
#!/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())
Đầu ra mẫu:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
Lưu ý rằng các IP không theo thứ tự, vì IP được in ngay khi nó trả lời, do đó, IP trả lời trước sẽ được in trước.
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"
Một cách đơn giản tôi chỉ cần nấu chín trong một phút..chỉ cần icmplib cần quyền riêng tư dưới đây hoạt động khá tốt! HTH