redes - Secuencias de comandos de ping mĂșltiples en Python
python ping script (8)
Este guión:
import subprocess
import os
with open(os.devnull, "wb") as limbo:
for n in xrange(1, 10):
ip="192.168.0.{0}".format(n)
result=subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2", ip],
stdout=limbo, stderr=limbo).wait()
if result:
print ip, "inactive"
else:
print ip, "active"
producirá algo como esta salida:
192.168.0.1 active
192.168.0.2 active
192.168.0.3 inactive
192.168.0.4 inactive
192.168.0.5 inactive
192.168.0.6 inactive
192.168.0.7 active
192.168.0.8 inactive
192.168.0.9 inactive
Puede capturar la salida si reemplaza el limbo
con subprocess.PIPE
y usa communicate()
en el objeto Popen
:
p=Popen( ... )
output=p.communicate()
result=p.wait()
De esta manera obtendrá el valor de retorno del comando y podrá capturar el texto. Siguiendo el manual esta es la forma preferida de operar un subproceso si necesita flexibilidad:
La creación y gestión del proceso subyacente en este módulo es manejada por la clase Popen. Ofrece mucha flexibilidad para que los desarrolladores puedan manejar los casos menos comunes que no están cubiertos por las funciones de conveniencia.
No puedo encontrar ninguna documentación buena y fácil de aprender sobre python y redes. En este caso, solo estoy tratando de hacer un script fácil que pueda hacer ping a varias máquinas remotas.
for ping in range(1,10):
ip="127.0.0."+str(ping)
os.system("ping -c 3 %s" % ip)
Un script simple como ese hará un ping a las máquinas, pero me gustaría que el script devuelva ''activo'' ''sin respuesta'' Lo que me hace pensar que también tendré que buscar el módulo de tiempo, creo que el time.sleep(5)
y después de eso, habría una declaración de ruptura. Lo que me hace pensar que debería haber un bucle mientras dentro. No estoy 100% seguro, podría estar yendo en la dirección equivocada por completo: / si alguien pudiera ayudarme o indicarme en la dirección de alguna documentación que sería genial.
Intenta subprocess.call
. Guarda el valor de retorno del programa que se utilizó.
Según mi manual de ping, devuelve 0 en caso de éxito, 2 cuando se enviaron pings pero no se recibió respuesta y cualquier otro valor indica un error.
# typo error in import
import subprocess
for ping in range(1,10):
address = "127.0.0." + str(ping)
res = subprocess.call([''ping'', ''-c'', ''3'', address])
if res == 0:
print "ping to", address, "OK"
elif res == 2:
print "no response from", address
else:
print "ping to", address, "failed!"
Muchas gracias por esto. Lo he modificado para que funcione con Windows. También puse un tiempo de espera bajo, por lo que los IP que no tienen retorno no se sentarán y esperarán 5 segundos cada uno. Esto es de código fuente hochl.
import subprocess
import os
with open(os.devnull, "wb") as limbo:
for n in xrange(200, 240):
ip="10.2.7.{0}".format(n)
result=subprocess.Popen(["ping", "-n", "1", "-w", "200", ip],
stdout=limbo, stderr=limbo).wait()
if result:
print ip, "inactive"
else:
print ip, "active"
Solo cambia la ip = para tu esquema y el rango para los hosts.
Para hacer ping a varios hosts a la vez, puede usar subprocess.Popen()
:
#!/usr/bin/env python3
import os
import time
from subprocess import Popen, DEVNULL
p = {} # ip -> process
for n in range(1, 100): # start ping processes
ip = "127.0.0.%d" % n
p[ip] = Popen([''ping'', ''-n'', ''-w5'', ''-c3'', ip], stdout=DEVNULL)
#NOTE: you could set stderr=subprocess.STDOUT to ignore stderr also
while p:
for ip, proc in p.items():
if proc.poll() is not None: # ping finished
del p[ip] # remove from the process list
if proc.returncode == 0:
print(''%s active'' % ip)
elif proc.returncode == 1:
print(''%s no response'' % ip)
else:
print(''%s error'' % ip)
break
Si puede ejecutarse como una raíz, podría usar un script de ping de Python puro o scapy
:
from scapy.all import sr, ICMP, IP, L3RawSocket, conf
conf.L3socket = L3RawSocket # for loopback interface
ans, unans = sr(IP(dst="127.0.0.1-99")/ICMP(), verbose=0) # make requests
ans.summary(lambda (s,r): r.sprintf("%IP.src% is alive"))
Python en realidad tiene un method realmente dulce que "devolverá un iterador a los hosts utilizables en la red". (configuración estricta a falsa iteración en todas las direcciones IP)
Por ejemplo:
import subprocess
import ipaddress
subnet = ipaddress.ip_network(''192.168.1.0/24'', strict=False)
for i in subnet.hosts():
i = str(i)
subprocess.call(["ping", "-c1", "-n", "-i0.1", "-W1", i])
El intervalo de espera (-i0.1) puede ser importante para las automatizaciones, incluso un tiempo de espera de un segundo (-t1) puede durar una duración de .0 / 24.
EDIT : Entonces, para rastrear las solicitudes de ICMP (ping), podemos hacer algo como esto:
#!/usr/bin/env python
import subprocess
import ipaddress
alive = []
subnet = ipaddress.ip_network(''192.168.1.0/23'', strict=False)
for i in subnet.hosts():
i = str(i)
retval = subprocess.call(["ping", "-c1", "-n", "-i0.1", "-W1", i])
if retval == 0:
alive.append(i)
for ip in alive:
print(ip + " is alive")
Que devolverá algo como:
192.168.0.1 is alive
192.168.0.2 is alive
192.168.1.1 is alive
192.168.1.246 is alive
es decir, todas las direcciones IP que responden a ICMP van desde un total de / 23-- ¡Muy bien!
Soy un principiante y escribí una secuencia de comandos para hacer ping a varios hosts. Para hacer ping a varios hosts, puede usar el módulo ipaddress.
import ipaddress
from subprocess import Popen, PIPE
net4 = ipaddress.ip_network(''192.168.2.0/24'')
for x in net4.hosts():
x = str(x)
hostup = Popen(["ping", "-c1", x], stdout=PIPE)
output = hostup.communicate()[0]
val1 = hostup.returncode
if val1 == 0:
print(x, "is pinging")
else:
print(x, "is not responding")
import subprocess
import os
''''''
servers.txt contains ip address in following format
192.168.1.1
192.168.1.2
''''''
with open(''servers.txt'', ''r'') as f:
for ip in f:
result=subprocess.Popen(["ping", "-c", "1", "-n", "-W", "2", ip],stdout=f, stderr=f).wait()
if result:
print(ip, "inactive")
else:
print(ip, "active")
import subprocess,os,threading,time
from queue import Queue
lock=threading.Lock()
_start=time.time()
def check(n):
with open(os.devnull, "wb") as limbo:
ip="192.168.21.{0}".format(n)
result=subprocess.Popen(["ping", "-n", "1", "-w", "300", ip],stdout=limbo, stderr=limbo).wait()
with lock:
if not result:
print (ip, "active")
else:
pass
def threader():
while True:
worker=q.get()
check(worker)
q.task_done()
q=Queue()
for x in range(255):
t=threading.Thread(target=threader)
t.daemon=True
t.start()
for worker in range(1,255):
q.put(worker)
q.join()
print("Process completed in: ",time.time()-_start)
Creo que esta será una mejor.