1. ホーム
  2. python

[解決済み】pythonで高速pingスイープ

2022-01-31 03:22:51

質問

そこで、bashスクリプトで行うのと同じような結果をpythonで得ようと思っています。

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スクリプトのすべてのバージョンで抱えている問題は、バッチスクリプトが数秒かかるのに比べて、完了するまでに非常に長い時間がかかるということです。

バッチファイルでは、/24ネットワークを掃引するのに約2秒かかりますが、パイソンスクリプトでは、最高で約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スクリプトの速度には到底及びません。

何か提案はありますか?

解決方法は?

マルチプロセシング

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