2014-01-20 66 views
6

所以,我試圖用python獲得類似的結果,就像我使用bash腳本一樣。Python中的快速ping掃描

代碼的bash腳本:

#!/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分鐘。

最新版本的python腳本的:

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

我試過在Python幾種不同的方式,但不能得到bash腳本的速度附近的任何地方。

有什麼建議嗎?

+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

這對我來說在一個/ 24網絡上花了10秒鐘。 – mojo

+0

'jobs.put(None)'的用途是什麼? @mojo – Isaias

+0

@Isaias每個None都表示沒有更多的工作。如果你修改了工作進程代碼,你可以結束()隊列並得到相似的結果。 – mojo