Réponses:
Cette fonction fonctionne dans n'importe quel système d'exploitation (Unix, Linux, macOS et Windows)
Python 2 et Python 3
EDITS:
Par @radato a os.system
été remplacé par subprocess.call
. Cela évite la vulnérabilité d' injection de shell dans les cas où votre chaîne de nom d'hôte pourrait ne pas être validée.
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
Notez que, selon @ikrase sous Windows, cette fonction reviendra toujours True
si vous obtenez une Destination Host Unreachable
erreur.
Explication
La commande est ping
à la fois dans les systèmes Windows et Unix.
L'option -n
(Windows) ou -c
(Unix) contrôle le nombre de paquets qui dans cet exemple a été défini sur 1.
platform.system()
renvoie le nom de la plateforme. Ex. 'Darwin'
sur macOS.
subprocess.call()
effectue un appel système. Ex. subprocess.call(['ls','-l'])
.
ping 8.8.8.8 -n 1
3) echo %ERRORLEVEL%
. Code: modifiez la dernière ligne du code Python en return system_call(command)
. Avec une connectivité appropriée, vous obtiendrez 0 (zéro). Avec votre modem éteint, vous devez obtenir un code d'erreur. Bien entendu, les deux méthodes doivent renvoyer le même code d'erreur dans les mêmes conditions.
Si vous n'avez pas besoin de prendre en charge Windows, voici une façon très concise de le faire:
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!'
Cela fonctionne car le ping renvoie une valeur différente de zéro si la connexion échoue. (La valeur de retour diffère en fait en fonction de l'erreur réseau.) Vous pouvez également modifier le délai d'expiration du ping (en secondes) à l'aide de l'option «-t». Notez que cela affichera du texte sur la console.
response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
man ping
pour être sûr.
hostname
chaîne d'un utilisateur, il pourrait facilement pirater votre serveur en vous donnant une "URL" comme 'google.com; rm -rf /*'
. Utilisez subprocess.run(["ping", "-c", "1", hostname]).returncode
plutôt.
Il existe un module appelé pyping qui peut le faire. Il peut être installé avec pip
pip install pyping
Il est assez simple à utiliser, cependant, lorsque vous utilisez ce module, vous avez besoin d'un accès root car il crée des paquets bruts sous le capot.
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')
solution. De plus, la pyping
bibliothèque est très facile à utiliser par rapport à l'utilisation de la bibliothèque de sockets TCP / IP. J'ai écrit mon programme ping en utilisant les deux, et il pyping
est beaucoup plus rapide et plus facile à utiliser, à mon avis, surtout si l'on n'est pas familier avec l'utilisation de la bibliothèque de sockets 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
pour obtenir le chemin correct.
ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Pour python3, il existe un module python ping3 très simple et pratique : ( pip install ping3
, nécessite les privilèges root ).
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
Ce module permet également la personnalisation de certains paramètres.
Parce que j'aime avoir mon programme Python universel sur les versions 2.7 et 3.x et sur les plateformes Linux, Mac OS et Windows, j'ai dû modifier les exemples existants.
# 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
vous pouvez bien sûr également utiliser platform.system().lower() != "windows"
.
os.name!="nt"
marche pas aussi? Certes, je ne l'ai pas essayé sur tous les combos ver / plateforme!
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
se trouve dans le tube, non?
Après avoir regardé autour de moi, j'ai fini par écrire mon propre module ping, conçu pour surveiller un grand nombre d'adresses, est asynchrone et n'utilise pas beaucoup de ressources système. Vous pouvez le trouver ici: https://github.com/romana/multi-ping/ Il est sous licence Apache, vous pouvez donc l'utiliser dans votre projet comme bon vous semble.
Les principales raisons de la mise en œuvre de la mienne sont les restrictions des autres approches:
#!/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()
Assurez-vous que pyping est installé ou installez-le pip install pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
Le ping ICMP programmatique est compliqué en raison des privilèges élevés requis pour envoyer des paquets ICMP bruts, et l'appel ping
binaire est moche. Pour la surveillance du serveur, vous pouvez obtenir le même résultat en utilisant une technique appelée ping TCP :
# 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
En interne, cela établit simplement une connexion TCP au serveur cible et la supprime immédiatement, en mesurant le temps écoulé. Cette implémentation particulière est un peu limitée en ce qu'elle ne gère pas les ports fermés, mais pour vos propres serveurs, cela fonctionne plutôt bien.
Je résous ceci avec:
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" est le moyen de savoir si le ping est correctement. Saludos
Ma réduction en utilisant les idées des réponses dans cet article, mais uniquement en utilisant le nouveau module de sous-processus recommandé et 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
pour renvoyer True ou False en fonction d'une condition. Il suffit d'utiliser eg shell_needed = operating_sys == 'Windows'
etreturn success == 0
Ce script fonctionne sur Windows, et devrait fonctionner sur d'autres OS: Il fonctionne sur Windows, Debian et macosx, nécessite un test sur 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
J'ai fini par trouver cette question concernant un scénario similaire. J'ai essayé le pyping mais l'exemple donné par Naveen n'a pas fonctionné pour moi sous Windows sous Python 2.7.
Un exemple qui a fonctionné pour moi est:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
pyping
ne semble pas être un module standard. Peut-être pourriez-vous fournir un lien?
En utilisant Multi-ping ( pip install multiPing
), j'ai créé ce code simple ( copiez et collez simplement si vous voulez! ):
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
Usage:
#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)
Si vous voulez un seul échantillon, le deuxième paramètre " 10
" peut être ignoré!
J'espère que ça aide!
Ma version d'une fonction 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
N'hésitez pas à l'utiliser comme vous le souhaitez.
Cela semble assez simple, mais m'a donné des crises. J'ai continué à obtenir "l'opération de socket ouverte icmp n'est pas autorisée" ou bien les solutions se bloqueraient si le serveur était hors ligne. Si, cependant, vous voulez savoir que le serveur est actif et que vous exécutez un serveur Web sur ce serveur, alors curl fera le travail. Si vous avez ssh et des certificats, alors ssh et une simple commande suffiront. Voici le code:
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
J'avais une exigence similaire, je l'ai donc implémentée comme indiqué ci-dessous. Il est testé sur Windows 64 bits et 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))
Lorsque l'adresse IP n'est pas accessible, subprocess.check_output () lève une exception. Une vérification supplémentaire peut être effectuée en extrayant les informations de la ligne de sortie «Paquets: envoyés = 2, reçus = 2, perdus = 0 (0% de perte)».
Voici une solution utilisant le subprocess
module Python et l' ping
outil CLI fourni par le système d'exploitation sous-jacent. Testé sous Windows et Linux. Prise en charge de la définition d'un délai d'expiration du réseau. N'a pas besoin de privilèges root (au moins sur Windows et 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
Utilisez ceci, il est testé sur python 2.7 et fonctionne correctement, il renvoie le temps de ping en millisecondes en cas de succès et renvoie False en cas d'échec.
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
Une chose que beaucoup de réponses manquent est que (au moins sous Windows) la ping
commande renvoie 0 (indiquant le succès) si elle reçoit la réponse «Hôte de destination inaccessible».
Voici mon code qui vérifie s'il b'TTL='
est dans la réponse, car cela n'est présent que lorsque le ping a atteint l'hôte. Remarque: la plupart de ce code est basé sur les autres réponses ici.
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'))
Remarque: Cela capture la sortie au lieu de l'imprimer, donc si vous voulez voir la sortie de ping
, vous devrez imprimer completedPing.stdout
avant de revenir.
WINDOWS UNIQUEMENT - Je ne peux pas croire que personne ne s'est ouvert Win32_PingStatus En utilisant une simple requête WMI, nous renvoyons un objet rempli d'informations très détaillées gratuitement
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'
Mon emprunt à d'autres réponses. Essayez de simplifier et de minimiser les requêtes.
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"
J'avais besoin d'un balayage de ping plus rapide et je ne voulais pas utiliser de bibliothèques externes, j'ai donc résolu d'utiliser la concurrence en utilisant intégré asyncio
.
Ce code nécessite python 3.7+ et est fabriqué et testé sous Linux uniquement . Cela ne fonctionnera pas sous Windows, mais je suis sûr que vous pouvez facilement le modifier pour qu'il fonctionne sur Windows.
Je ne suis pas un expert avec asyncio
mais j'ai utilisé cet excellent article Accélérez votre programme Python avec la concurrence et j'ai proposé ces lignes de codes. J'ai essayé de le rendre aussi simple que possible, vous devrez donc probablement y ajouter plus de code pour répondre à vos besoins.
Il ne renvoie ni vrai ni faux, j'ai pensé qu'il serait plus pratique de lui faire imprimer l'adresse IP qui répond à une demande de ping. Je pense que c'est assez rapide, avec un ping de 255 ips en près de 10 secondes.
#!/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())
Exemple de sortie:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
Notez que les adresses IP ne sont pas dans l'ordre, car l'adresse IP est imprimée dès qu'elle répond, donc celle qui répond en premier est imprimée en premier.
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"
Un simple que je viens de préparer en une minute ... en utilisant icmplib, il faut des privilèges root, le ci-dessous fonctionne plutôt bien! HTH