Jawaban:
Fungsi ini berfungsi di semua OS (Unix, Linux, macOS, dan Windows)
Python 2 dan Python 3
EDIT:
Oleh @radato os.system
digantikan oleh subprocess.call
. Ini menghindari kerentanan injeksi shell jika string nama host Anda mungkin tidak divalidasi.
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
Perhatikan bahwa, menurut @ikrase pada Windows, fungsi ini masih akan kembali True
jika Anda mendapatkan Destination Host Unreachable
kesalahan.
Penjelasan
Perintahnya ada ping
di sistem Windows dan Unix-like.
Opsi -n
(Windows) atau -c
(Unix) mengontrol jumlah paket yang dalam contoh ini diatur ke 1.
platform.system()
mengembalikan nama platform. Ex. 'Darwin'
di macOS.
subprocess.call()
melakukan panggilan sistem. Ex. subprocess.call(['ls','-l'])
.
ping 8.8.8.8 -n 1
3) echo %ERRORLEVEL%
. Kode: Ubah baris terakhir kode Python menjadi return system_call(command)
. Dengan konektivitas yang tepat Anda akan mendapatkan 0 (nol). Dengan modem Anda mati, Anda harus mendapatkan beberapa kode kesalahan. Tentu saja, kedua metode harus mengembalikan kode kesalahan yang sama dalam kondisi yang sama.
Jika Anda tidak perlu mendukung Windows, berikut ini cara yang sangat ringkas untuk melakukannya:
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!'
Ini berfungsi karena ping mengembalikan nilai bukan nol jika koneksi gagal. (Nilai pengembalian sebenarnya berbeda tergantung pada kesalahan jaringan.) Anda juga bisa mengubah batas waktu ping (dalam detik) menggunakan opsi '-t'. Catatan, ini akan menampilkan teks ke konsol.
response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
man ping
untuk memastikan.
hostname
string dari pengguna, mereka dapat dengan mudah meretas server Anda dengan memberi Anda "url"'google.com; rm -rf /*'
. Gunakan subprocess.run(["ping", "-c", "1", hostname]).returncode
sebagai gantinya.
Ada modul yang disebut pyping yang dapat melakukan ini. Itu dapat diinstal dengan pip
pip install pyping
Sangat mudah digunakan, namun, ketika menggunakan modul ini, Anda memerlukan akses root karena fakta bahwa itu adalah pembuatan paket mentah di bawah tenda.
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')
solusi. Plus pyping
lib sangat mudah digunakan dibandingkan dengan menggunakan perpustakaan soket TCP / IP. Saya menulis program ping saya menggunakan keduanya, dan pyping
jauh lebih cepat dan lebih mudah digunakan, menurut pendapat saya, terutama jika orang tidak terbiasa dengan menggunakan perpustakaan soket 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
untuk mendapatkan jalur yang benar.
ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Untuk python3 ada modul python ping3 yang sangat sederhana dan nyaman : (pip install ping3
, membutuhkan hak akses root ).
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
Modul ini memungkinkan penyesuaian beberapa parameter juga.
Karena saya suka memiliki program Python universal pada versi 2.7 dan 3.x dan pada platform Linux, Mac OS dan Windows, saya harus memodifikasi contoh yang ada.
# 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
tentunya Anda bisa juga menggunakan saja platform.system().lower() != "windows"
.
os.name!="nt"
juga berfungsi? Memang saya belum mencobanya di semua kombo 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
ditemukan di dalam pipa, bukan?
Setelah melihat-lihat, saya akhirnya menulis modul ping saya sendiri, yang dirancang untuk memonitor sejumlah besar alamat, tidak sinkron dan tidak menggunakan banyak sumber daya sistem. Anda dapat menemukannya di sini: https://github.com/romana/multi-ping/ Ini berlisensi Apache, sehingga Anda dapat menggunakannya dalam proyek Anda dengan cara apa pun yang Anda inginkan.
Alasan utama untuk menerapkan saya sendiri adalah pembatasan dari pendekatan lain:
#!/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()
Pastikan pyping diinstal atau instal pip instal pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
Ping ICMP terprogram rumit karena hak istimewa tinggi yang diperlukan untuk mengirim paket ICMP mentah, dan memanggil ping
biner jelek. Untuk pemantauan server, Anda dapat mencapai hasil yang sama menggunakan teknik yang disebut 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
Secara internal, ini hanya membuat koneksi TCP ke server target dan langsung menjatuhkannya, mengukur waktu yang berlalu. Implementasi khusus ini agak terbatas karena tidak menangani port yang tertutup tetapi untuk server Anda sendiri ia bekerja dengan cukup baik.
Saya menyelesaikan ini dengan:
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" adalah cara untuk mengetahui apakah ping itu benar. Salud
Pengurangan saya menggunakan ide dari jawaban dalam posting ini tetapi hanya menggunakan modul subproses yang direkomendasikan dan python3 yang lebih baru:
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
untuk mengembalikan Benar atau Salah berdasarkan kondisi. Cukup gunakan mis shell_needed = operating_sys == 'Windows'
danreturn success == 0
Skrip ini berfungsi pada Windows, dan harus bekerja pada OS lain: Ini berfungsi pada Windows, Debian, dan macosx, perlu tes pada 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
Saya akhirnya menemukan pertanyaan ini mengenai skenario yang sama. Saya mencoba pyping tetapi contoh yang diberikan oleh Naveen tidak bekerja untuk saya di Windows di bawah Python 2.7.
Contoh yang berhasil bagi saya adalah:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
pyping
tampaknya bukan modul standar. Mungkin Anda bisa memberikan tautan?
Menggunakan Multi-ping ( pip install multiPing
) saya membuat kode sederhana ini ( cukup salin dan tempel jika mau! ):
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
Pemakaian:
#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)
Jika Anda ingin sampel tunggal, " 10
" parameter kedua dapat diabaikan!
Semoga ini bisa membantu!
Versi saya dari fungsi 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
Jangan ragu untuk menggunakannya sesuka Anda.
Tampaknya cukup sederhana, tetapi memberi saya cocok. Saya terus mendapatkan "operasi soket terbuka icmp tidak diizinkan" atau solusi akan menutup jika server off line. Namun, jika yang ingin Anda ketahui adalah bahwa server masih hidup dan Anda menjalankan server web di server itu, maka curl akan melakukan pekerjaan itu. Jika Anda memiliki ssh dan sertifikat, maka ssh dan perintah sederhana sudah cukup. Ini kodenya:
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
Saya memiliki persyaratan yang serupa jadi saya menerapkannya seperti yang ditunjukkan di bawah ini. Ini diuji pada Windows 64 bit dan 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))
Ketika IP tidak dapat dijangkau, subprocess.check_output () memunculkan pengecualian. Verifikasi ekstra dapat dilakukan dengan mengekstraksi informasi dari baris keluaran 'Paket: Terkirim = 2, Diterima = 2, Hilang = 0 (kerugian 0%)'.
Inilah solusi menggunakan subprocess
modul Python dan ping
alat CLI yang disediakan oleh OS yang mendasarinya. Diuji pada Windows dan Linux. Dukungan pengaturan batas waktu jaringan. Tidak memerlukan hak akses root (setidaknya di Windows dan 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
Gunakan ini diuji pada python 2.7 dan berfungsi baik mengembalikan waktu ping dalam milidetik jika berhasil dan mengembalikan False saat gagal.
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
Satu hal yang terlewatkan oleh banyak jawaban adalah (setidaknya di Windows) ping
perintah mengembalikan 0 (menunjukkan keberhasilan) jika menerima balasan "Host tujuan tidak dapat dijangkau."
Berikut adalah kode saya yang memeriksa apakah b'TTL='
ada dalam respons, karena hanya ada saat ping mencapai host. Catatan: Sebagian besar kode ini didasarkan pada jawaban lain di sini.
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'))
Catatan: Ini menangkap output alih-alih mencetaknya, jadi jika Anda ingin melihat outputnya ping
, Anda harus mencetak completedPing.stdout
sebelum kembali.
WINDOWS ONLY - Tidak dapat dipercaya tidak ada yang membuka Win32_PingStatus menggunakan kueri WMI sederhana, kami mengembalikan objek yang penuh dengan informasi yang sangat detail secara gratis
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'
Saya menerima pinjaman dari jawaban lain. Berusaha menyederhanakan dan meminimalkan pertanyaan.
import platform, os
def ping(host):
result = os.popen(' '.join(("ping", ping.param, host))).read()
return 'TTL=' in result
ping.param = "-n 1" if platform.system().lower() == "windows" else "-c 1"
Saya memerlukan sapuan ping yang lebih cepat dan saya tidak ingin menggunakan perpustakaan eksternal, jadi saya memutuskan untuk menggunakan konkurensi menggunakan built-in asyncio
.
Kode ini membutuhkan python 3.7+ dan dibuat dan diuji di Linux saja. Itu tidak akan berfungsi pada Windows tetapi saya yakin Anda dapat dengan mudah mengubahnya untuk bekerja pada Windows.
Saya bukan ahli dengan asyncio
tetapi saya menggunakan artikel hebat ini Mempercepat Program Python Anda Dengan Concurrency dan saya datang dengan baris kode ini. Saya mencoba membuatnya sesederhana mungkin, jadi kemungkinan besar Anda perlu menambahkan lebih banyak kode sesuai kebutuhan Anda.
Itu tidak mengembalikan benar atau salah, saya pikir akan lebih nyaman hanya dengan membuatnya mencetak IP yang menanggapi permintaan ping. Saya pikir ini cukup cepat, ping 255 ips dalam hampir 10 detik.
#!/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())
Output sampel:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
Perhatikan bahwa IP tidak dalam urutan, karena IP dicetak segera setelah itu menjawab, sehingga yang menjawab pertama akan dicetak terlebih dahulu.
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"
Yang sederhana saya baru saja memasak dalam satu menit..menggunakan icmplib membutuhkan root privs di bawah ini bekerja cukup baik! HTH