2012-08-23 42 views
16

No puedo encontrar ninguna buena documentación 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.Varios script de ping en Python

for ping in range(1,10): 
    ip="127.0.0."+str(ping) 
    os.system("ping -c 3 %s" % ip) 

Una secuencia de comandos simple como que va a sondear las máquinas bien, pero me gustaría obtener la secuencia de comandos para devuelve 'activo' 'sin respuesta' que me hace pensar que voy a tener que buscar el módulo de tiempo también, creo que time.sleep(5) y después de eso, habría una declaración de interrupción. Lo que me hace pensar que debería haber un ciclo while dentro. No estoy 100% seguro, podría estar yendo en la dirección equivocada por completo:/si alguien pudiera ayudarme o apuntarme en la dirección de alguna documentación que sería genial.

+0

No estoy seguro de por qué crees que necesitas el módulo de tiempo? Sugiero que investigue cómo analizar el STDOUT de un [subproceso] (http://docs.python.org/library/subprocess.html#module-subprocess) (que es lo que debería estar usando en lugar de 'os.system() ') – ernie

+2

Pruebe [Scapy] (http://www.secdev.org/projects/scapy/). – kichik

+0

Aquí hay un ejemplo de https://github.com/lbaby/javalearn/blob/master/shell/ppe.py – lbaby

Respuesta

7

Este script:

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 esto de 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 se reemplaza limbo con subprocess.PIPE y utilizar communicate() en el Popen objeto:

p=Popen(...) 
output=p.communicate() 
result=p.wait() 

De esta forma obtienes el valor de retorno del comando y puedes capturar el texto. Tras la manual esta es la forma preferida de operar un subproceso si necesita flexibilidad:

La creación y gestión de procesos subyacentes en este módulo es manejado por la clase Popen. Ofrece una gran flexibilidad para que los desarrolladores de puedan manejar los casos menos comunes que no están cubiertos por las funciones de conveniencia .

+0

Por favor, deje un comentario con una explicación de por qué votó en contra, por lo que la respuesta se puede mejorar. – hochl

22

Trate subprocess.call. Guarda el valor de retorno del programa que se usó.

De acuerdo con 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!" 
+0

wow ... gracias chicos, realmente aprecio toda su ayuda. paz :) – kuiper

+3

Eres bienvenido. Recuerde marcar las respuestas que lo ayudaron como aceptado (haga clic en el tick verde debajo del conteo de votos de la pregunta), señala a los demás visitantes que la respuesta fue útil. :-) –

+1

'subprocess.call()' muestra solo una ip a la vez. Para hacer ping a múltiples ips simultáneamente ['subprocess.Popen()' podría usarse] (http://stackoverflow.com/a/12102040/4279) – jfs

1

Para hacer ping a varios equipos a la vez se puede utilizar 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 ejecutar como raíz se puede utilizar un pure Python ping script 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")) 
5

Gracias por lo mucho para esto Lo he modificado para que funcione con Windows. También puse un tiempo de espera bajo, por lo tanto, las IP que no tienen retorno no se sentarán y esperarán 5 segundos cada una. Esto es del 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" 

Simplemente cambie el ip = para su esquema y el xrange para los hosts.

0
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") 
3

Soy un principiante y escribí un script 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") 
-1
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 esto será mejor.

0

Python en realidad tiene un muy dulce method que 'devolverá un iterador sobre los hosts utilizables en la red'. (Ajuste estricto a las falsas itera sobre todas las IPs)

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 automatizaciones, incluso un segundo de tiempo de espera (-t1) puede tomar siempre a través de una .0/24

EDITAR: por lo tanto, con el fin de realizar un seguimiento de ICMP (ping) peticiones, 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, todos los proyectos de investigación que respondan a ICMP que van a través de una entera/23-- muy bien!

+0

FYI, arrojé errores sobre esto hasta especificar que la dirección IP fuera unicode: subred = ipaddress.ip_network (u'192.168.1.0/23 ', strict = False) – blackappy