2014-01-20 7 views
6

Also, ich versuche, ähnliche Ergebnisse mit Python zu bekommen, wie ich mit einem Bash-Skript.Schneller Ping-Sweep in Python

-Code für den Bash-Skript:

#!/bin/bash 

    for ip in $(seq 1 254); do 
     ping -c 1 10.10.10.$ip | grep "bytes from" | cut -d " " -f 4 | cut -d ":" -f 1 & 
    done 

Die Sache, die ich tun möchte, ist die gleichen Ergebnisse mit ähnlicher Geschwindigkeit. Das Problem, das ich mit jeder Version des Python-Skripts hatte, ist, dass es im Vergleich zu den wenigen Sekunden, die das Batch-Skript benötigt, sehr lange dauert.

Die Batch-Datei dauert etwa 2 Sekunden, um ein/24 Netzwerk zu fegen, während das Beste, was ich mit dem Python-Skript bekommen kann, etwa 5-8 Minuten ist.

Die neueste Version des Python-Skript:

import subprocess 

cmdping = "ping -c1 10.10.10." 

for x in range (2,255): 
    p = subprocess.Popen(cmdping+str(x), shell=True, stderr=subprocess.PIPE) 

    while True: 
     out = p.stderr.read(1) 
     if out == '' and p.poll() != None: 
      break 
     if out != '': 
      sys.stdout.write(out) 
      sys.stdout.flush() 

ich verschiedene Möglichkeiten in Python versucht haben, kann aber nicht überall in der Nähe der Geschwindigkeit des Bash-Skript bekommen.

Irgendwelche Vorschläge?

+0

Können Sie das konkretisieren - wie lange ist „sehr lange“ im Vergleich zu „wenigen Sekunden“? –

+3

Das Und-Zeichen am Ende des Bash-Skripts bewirkt, dass die Prozesse im Hintergrund ausgeführt werden. Ihr Python-Skript führt sie alle nacheinander aus. – Blender

+0

Die Batch-Datei dauert etwa 2 Sekunden, um ein/24-Netzwerk zu durchsuchen, während das Beste, was ich mit dem Python-Skript bekommen kann, etwa 5-8 Minuten ist. –

Antwort

13

Multiprocessing

#!/usr/bin/python2 

import multiprocessing 
import subprocess 
import os 

def pinger(job_q, results_q): 
    DEVNULL = open(os.devnull,'w') 
    while True: 
     ip = job_q.get() 
     if ip is None: break 

     try: 
      subprocess.check_call(['ping','-c1',ip], 
            stdout=DEVNULL) 
      results_q.put(ip) 
     except: 
      pass 

if __name__ == '__main__': 
    pool_size = 255 

    jobs = multiprocessing.Queue() 
    results = multiprocessing.Queue() 

    pool = [ multiprocessing.Process(target=pinger, args=(jobs,results)) 
      for i in range(pool_size) ] 

    for p in pool: 
     p.start() 

    for i in range(1,255): 
     jobs.put('192.168.1.{0}'.format(i)) 

    for p in pool: 
     jobs.put(None) 

    for p in pool: 
     p.join() 

    while not results.empty(): 
     ip = results.get() 
     print(ip) 
+0

Dies dauerte 10 Sekunden auf einem/24-Netzwerk für mich. – mojo

+0

Was ist der Zweck von 'jobs.put (None)'? @mojo – Isaias

+0

@Isaias Jede None ist ein Signal, dass es keine Jobs mehr gibt. Sie können die Warteschlange möglicherweise beenden() und ähnliche Ergebnisse erhalten, wenn Sie den Arbeitsprozesscode geändert haben. – mojo

Verwandte Themen