2014-01-20 31 views
6

私はbashスクリプトと同様に、Pythonを使って同様の結果を得ようとしています。 bashスクリプトのためのPythonの高速pingスイープ

コード:

#!/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スクリプトのすべてのバージョンで持っていた問題は、バッチスクリプトが実行する数秒に比べて、完了に非常に時間がかかることです。

バッチファイルは/ 24ネットワークをスイープするのに約2秒かかりますが、私がpythonスクリプトを入手するのに最適なのは約5-8分です。 Pythonスクリプトの

最新版:私はPythonでいくつかの異なる方法を試してみたが、bashスクリプトの速度近くでどこに行くことができない

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スクリプトはそれらをすべて1つずつ実行します。 – Blender

+0

バッチファイルは/ 24ネットワークをスイープするのに約2秒かかりますが、私が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

これは/ 24ネットワークで10秒かかりました。 – mojo

+0

'jobs.put(None)'の目的は何ですか? @mojo – Isaias

+0

@Isaiasそれぞれは、これ以上ジョブがないという信号です。ワーカープロセスコードを変更すると、キューを終了()して同様の結果を得ることができます。 – mojo