デフォルトでは、pingはパケットが到着するまで10秒間待機します。多くのアドレスは使用されていないか、またはこれらのアドレスを持つコンピュータはICMPエコー(ping)パケットに応答しませんので、最大2550秒間待機します。
あなたははCtrl +Cを入力すると、あなたは待機を中止SIGTERM
信号を送ります。 ICMPエコー応答を受信する前にpingを中止すると、誤った結果が得られます。ローカルネットワークはかなり速いので、これに遭遇する可能性は低いです。
これをスピードアップするには、次の2つの方法であなたのアプローチを変更することができます応答が来ていないとき
- が早くあきらめます。
-W
パラメータを渡します。たとえば、ping -c 1 -W 1 ...
を実行すると、pingは1秒間待機するため、プログラム全体では約250秒かかることになります。
- pingを並行して実行します。手動で行うことができます。通常は、スレッド/プロセスの
Pool
(またはpingごとに1つのスレッド/プロセス)を使用します。ご使用のオペレーティングシステムでは、1秒あたりのping数が制限される場合があります。たとえば、タイムアウトを10秒にして、すべてのpingを同時に実行すると、プログラムはわずか10秒しかかかりません。あなたの周りいじるていない場合は、プールを使用して
適切なコードが
import multiprocessing
import subprocess
TIMEOUT = 5 # in seconds
CONCURRENCY = 100 # how many pings in parallel?
def ping(ip):
""" Returns true iff the host is reachable. """
# print('ping %s' % ip) # uncomment to see progress
ret = subprocess.call(
['ping', '-W', str(TIMEOUT), '-c', '1', ip],
stdout=subprocess.DEVNULL)
if ret == 0:
print('%s is reachable' % ip)
ips = ('10.0.0.%d' % i for i in range(1, 255))
with multiprocessing.Pool(CONCURRENCY) as p:
p.map(ping, ips)
ようになり、あなたはまた、並行して実行んプログラムの代わりにpingを使用することをお勧めします。すべてのポートスキャナ(nmapなど)は正常に動作するはずです。
'multiprocessing'は開始する場所です。あなたの 'i'は数値であることが保証されているのでここでは安全ですが、一般的に*文字列連結を使用してシェルコマンドを形成することは非常に安全ではありません。 'stdout = open( '/ dev/null'、 'wb')'のように '>/dev/null'リダイレクションを非シェル依存のものに置き換えた' subprocess.Popen'に配列を渡します)はるかに良い形です。 –
もちろん、それは '極度に遅い'でしょう - 潜在的なホストにpingをしてから応答を待つのに時間がかかり、それを255回行います。 'nmap -sP --max-retries = 1 --host-timeout = 500ms 10.0.0。{}>/dev/null"あなたのシステムに 'nmap 'があるなら、 .format(i)) 'を使って500ms後にはあきらめますが、他にも示唆されているように、すべてを並行して実行したい場合はマルチプロセッシングを使わなければなりません。 – zwer
@jersten、... GILがここで問題になることは確かではありません。作業はサブプロセスを待っているからです。待機はロックの外になければなりません。 SIGCHLDが来たときに結果を処理するだけでは、厳密にロックを保持する必要があります。 –