2014-01-20 2 views
6

Итак, я пытаюсь получить аналогичные результаты с помощью python, как и с скриптом bash.Быстрый ping sweep в python

Код для сценария Баш:

#!/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 

Дело в том, что я хотел бы сделать, это получить те же результаты, с той же скоростью. Проблема, которая у меня была с каждой версией скрипта python, заключается в том, что для завершения требуется очень много времени, по сравнению с несколькими секундами, которые выполняет пакетный скрипт.

Пакетный файл занимает около 2 секунд, чтобы прокрутить сеть/24, в то время как лучшее, что я могу получить с помощью скрипта python, составляет около 5-8 минут.

Последняя версия питона сценария:

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() 

Я пробовал несколько различных способов в питона, но не может получить какой-либо скорости сценария Баш.

Любые предложения?

+0

Можете ли вы быть более точным - как долго это «очень долго» по сравнению с «несколько секунд»? –

+3

Этот амперсанд в конце сценария bash заставляет процессы работать в фоновом режиме. Ваш скрипт Python запускает их все по одному. – Blender

+0

Пакетный файл занимает около 2 секунд, чтобы прокрутить сеть/24, в то время как лучшее, что я могу получить с помощью скрипта python, составляет около 5-8 минут. –

ответ

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

Для меня потребовалось 10 секунд в сети/24. – mojo

+0

Какова цель 'jobs.put (None)'? @mojo – Isaias

+0

@Isaias Каждый None - это сигнал, что больше нет заданий. Возможно, вы закончите() очередь и получите аналогичные результаты, если измените код рабочего процесса. – mojo

Смежные вопросы