Respuestas:
Esta función funciona en cualquier sistema operativo (Unix, Linux, macOS y Windows)
Python 2 y Python 3
EDICIONES:
Por @radato os.system
fue reemplazado por subprocess.call
. Esto evita la vulnerabilidad de inyección de shell en los casos en que su cadena de nombre de host podría no estar validada.
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
Tenga en cuenta que, según @ikrase en Windows, esta función seguirá regresando True
si obtiene un Destination Host Unreachable
error.
Explicación
El comando está ping
en Windows y en sistemas similares a Unix.
La opción -n
(Windows) o -c
(Unix) controla la cantidad de paquetes que en este ejemplo se estableció en 1.
platform.system()
devuelve el nombre de la plataforma. Ex. 'Darwin'
en macOS
subprocess.call()
realiza una llamada al sistema. Ex. subprocess.call(['ls','-l'])
.
ping 8.8.8.8 -n 1
3) echo %ERRORLEVEL%
. Código: modifique la última línea del código de Python a return system_call(command)
. Con la conectividad adecuada obtendrá 0 (cero). Con su módem apagado, debe obtener un código de error. Por supuesto, ambos métodos deben devolver el mismo código de error en las mismas condiciones.
Si no necesita admitir Windows, esta es una forma muy concisa de hacerlo:
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!'
Esto funciona porque ping devuelve un valor distinto de cero si falla la conexión. (El valor de retorno en realidad difiere según el error de la red). También puede cambiar el tiempo de espera de ping (en segundos) utilizando la opción '-t'. Tenga en cuenta que esto enviará texto a la consola.
response = os.system("ping -c 1 -w2 " + hostname + " > /dev/null 2>&1")
man ping
para asegurarse.
hostname
cadena de un usuario, podría hackear fácilmente su servidor dándole un "url" como 'google.com; rm -rf /*'
. Usar en su subprocess.run(["ping", "-c", "1", hostname]).returncode
lugar.
Hay un módulo llamado pyping que puede hacer esto. Se puede instalar con pip
pip install pyping
Es bastante simple de usar, sin embargo, al usar este módulo, necesita acceso a la raíz debido al hecho de que está creando paquetes sin procesar bajo el capó.
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')
solución. Además, la pyping
lib es muy fácil de usar en comparación con el uso de la biblioteca de sockets TCP / IP. Escribí mi programa de ping usando ambos, y pyping
es mucho más rápido y fácil de usar, en mi opinión, especialmente si uno no está familiarizado con el uso de la biblioteca 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
para obtener el camino correcto.
ping_response = subprocess.Popen(["ping", hostname, "-n", '1'], stdout=subprocess.PIPE).stdout.read()
Para python3 hay un módulo de python muy simple y conveniente ping3 : ( pip install ping3
, necesita privilegios de root ).
from ping3 import ping, verbose_ping
ping('example.com') # Returns delay in seconds.
>>> 0.215697261510079666
Este módulo también permite la personalización de algunos parámetros.
Como me gusta que mi programa Python sea universal en la versión 2.7 y 3.xy en la plataforma Linux, Mac OS y Windows, tuve que modificar los ejemplos existentes.
# 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
usted, por supuesto, también podría usarlo platform.system().lower() != "windows"
.
os.name!="nt"
funciona también? ¡Es cierto que no lo he probado en todos los combos ver / plataforma!
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 encuentra en la tubería, ¿no?
Después de mirar alrededor, terminé escribiendo mi propio módulo de ping, que está diseñado para monitorear grandes cantidades de direcciones, es asíncrono y no utiliza muchos recursos del sistema. Puede encontrarlo aquí: https://github.com/romana/multi-ping/ Tiene licencia de Apache, por lo que puede usarlo en su proyecto de la manera que mejor le parezca.
Las principales razones para implementar el mío son las restricciones de los otros enfoques:
#!/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()
Asegúrese de que pyping esté instalado o instálelo pip install pyping
#!/usr/bin/python
import pyping
response = pyping.ping('Your IP')
if response.ret_code == 0:
print("reachable")
else:
print("unreachable")
El ping programático ICMP es complicado debido a los elevados privilegios necesarios para enviar paquetes ICMP sin procesar, y llamar a ping
binarios es feo. Para la supervisión del servidor, puede lograr el mismo resultado utilizando una técnica llamada ping de 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
Internamente, esto simplemente establece una conexión TCP con el servidor de destino y la deja de inmediato, midiendo el tiempo transcurrido. Esta implementación particular es un poco limitada ya que no maneja puertos cerrados, pero para sus propios servidores funciona bastante bien.
Resuelvo esto con:
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" es la forma de saber si el ping es correcto. Saludos
Mi reducción usando ideas de respuestas en esta publicación pero solo usando el módulo de subproceso más nuevo recomendado y 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
para devolver Verdadero o Falso en función de una condición. Solo use eg shell_needed = operating_sys == 'Windows'
yreturn success == 0
Este script funciona en Windows y debería funcionar en otros sistemas operativos: funciona en Windows, Debian y Macosx, necesita una prueba en 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
Terminé encontrando esta pregunta con respecto a un escenario similar. Probé pyping pero el ejemplo dado por Naveen no funcionó para mí en Windows en Python 2.7.
Un ejemplo que funcionó para mí es:
import pyping
response = pyping.send('Your IP')
if response['ret_code'] == 0:
print("reachable")
else:
print("unreachable")
pyping
no parece ser un módulo estándar. Tal vez podría proporcionar un enlace?
Usando Multi-ping ( pip install multiPing
) hice este código simple (¡ simplemente copie y pegue si lo desea! ):
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
Uso:
#Getting the latency average (in seconds) of host '192.168.0.123' using 10 samples
ping('192.168.0.123',10)
Si desea una sola muestra, 10
¡puede ignorar el segundo parámetro " "!
¡Espero eso ayude!
Mi versión de una función de 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
Siéntase libre de usarlo como lo desee.
Parece bastante simple, pero me dio ataques. Seguía recibiendo "no se permite la operación de socket abierto de icmp" o de lo contrario las soluciones se colgarían si el servidor estuviera fuera de línea. Sin embargo, si lo que quiere saber es que el servidor está vivo y está ejecutando un servidor web en ese servidor, entonces curl hará el trabajo. Si tiene ssh y certificados, entonces ssh y un simple comando serán suficientes. Aquí está el código:
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
Tenía un requisito similar, así que lo implementé como se muestra a continuación. Está probado en Windows 64 bit y 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))
Cuando no se puede acceder a IP, subprocess.check_output () genera una excepción. La verificación adicional se puede hacer extrayendo información de la línea de salida 'Paquetes: Enviado = 2, Recibido = 2, Perdido = 0 (0% de pérdida)'.
Aquí hay una solución que utiliza el subprocess
módulo de Python y la ping
herramienta CLI proporcionada por el SO subyacente. Probado en Windows y Linux. Soporte para establecer un tiempo de espera de red. No necesita privilegios de root (al menos en Windows y 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
Use esto, se probó en Python 2.7 y funciona bien, devuelve el tiempo de ping en milisegundos si tiene éxito y devuelve False en caso de error.
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
Una cosa que muchas de las respuestas pierden es que (al menos en Windows) ping
comando devuelve 0 (lo que indica éxito) si recibe la respuesta "Host de destino inalcanzable".
Aquí está mi código que verifica si b'TTL='
está en la respuesta, ya que solo está presente cuando el ping llegó al host. Nota: La mayor parte de este código se basa en las otras respuestas aquí.
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'))
Nota: Esto captura el resultado en lugar de imprimirlo, por lo que si desea ver el resultado ping
, deberá imprimir completedPing.stdout
antes de regresar.
SOLO WINDOWS: no puedo creer que nadie haya abierto Win32_PingStatus. Mediante una simple consulta WMI, devolvemos un objeto lleno de información realmente detallada de forma gratuita
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'
Mi toma prestada de otras respuestas. Intente simplificar y minimizar las consultas.
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"
Necesitaba un barrido de ping más rápido y no quería usar ninguna biblioteca externa, así que decidí usar la simultaneidad usando el incorporado asyncio
.
Este código requiere python 3.7+ y está hecho y probado solo en Linux . No funcionará en Windows, pero estoy seguro de que puede cambiarlo fácilmente para que funcione en Windows.
No soy un experto asyncio
pero utilicé este excelente artículo Acelere su programa Python con concurrencia y se me ocurrieron estas líneas de códigos. Traté de hacerlo lo más simple posible, por lo que lo más probable es que necesite agregar más código para satisfacer sus necesidades.
No devuelve verdadero o falso, pensé que sería más conveniente hacer que imprima la IP que responde a una solicitud de ping. Creo que es bastante rápido, haciendo ping a 255 ips en casi 10 segundos.
#!/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())
Salida de muestra:
192.168.1.1
192.168.1.3
192.168.1.102
192.168.1.106
192.168.1.6
Tenga en cuenta que las IP no están en orden, ya que la IP se imprime tan pronto como responde, por lo que el que responde primero se imprime primero.
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"
Una simple que acabo de cocinar en un minuto ... ¡usar icmplib necesita root privs, el siguiente funciona bastante bien! HTH