patternpythonMinor
Pinging a list of hosts
Viewed 0 times
listhostspinging
Problem
I have a simple script that will take a list of hosts and ping each host (there's about 200) a single time before moving on. This is not the most effecient method I am sure, as it is very linear. And it takes a few minutes to complete. I would ideally like to run this script every minute (so each IP address is checked every minute (the actual running of the script is controlled externally).
I was looking for some pointers on potentially making the script more effecient/dynamic.
I was looking for some pointers on potentially making the script more effecient/dynamic.
import sys
import os
import platform
import subprocess
plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir, 'hosts.txt')
hostsFile = open(hosts, "r")
lines = hostsFile.readlines()
if plat == "Windows":
for line in lines:
line = line.strip( )
ping = subprocess.Popen(
["ping", "-n", "1", "-l", "1", "-w", "100", line],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
out, error = ping.communicate()
print out
print error
if plat == "Linux":
for line in lines:
line = line.strip( )
ping = subprocess.Popen(
["ping", "-c", "1", "-l", "1", "-s", "1", "-W", "1", line],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
out, error = ping.communicate()
print out
print error
hostsFile.close()Solution
Here's a solution using threads:
import sys
import os
import platform
import subprocess
import Queue
import threading
def worker_func(pingArgs, pending, done):
try:
while True:
# Get the next address to ping.
address = pending.get_nowait()
ping = subprocess.Popen(ping_args + [address],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
out, error = ping.communicate()
# Output the result to the 'done' queue.
done.put((out, error))
except Queue.Empty:
# No more addresses.
pass
finally:
# Tell the main thread that a worker is about to terminate.
done.put(None)
# The number of workers.
NUM_WORKERS = 4
plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir, 'hosts.txt')
# The arguments for the 'ping', excluding the address.
if plat == "Windows":
pingArgs = ["ping", "-n", "1", "-l", "1", "-w", "100"]
elif plat == "Linux":
pingArgs = ["ping", "-c", "1", "-l", "1", "-s", "1", "-W", "1"]
else:
raise ValueError("Unknown platform")
# The queue of addresses to ping.
pending = Queue.Queue()
# The queue of results.
done = Queue.Queue()
# Create all the workers.
workers = []
for _ in range(NUM_WORKERS):
workers.append(threading.Thread(target=worker_func, args=(pingArgs, pending, done)))
# Put all the addresses into the 'pending' queue.
with open(hosts, "r") as hostsFile:
for line in hostsFile:
pending.put(line.strip())
# Start all the workers.
for w in workers:
w.daemon = True
w.start()
# Print out the results as they arrive.
numTerminated = 0
while numTerminated < NUM_WORKERS:
result = done.get()
if result is None:
# A worker is about to terminate.
numTerminated += 1
else:
print result[0] # out
print result[1] # error
# Wait for all the workers to terminate.
for w in workers:
w.join()Code Snippets
import sys
import os
import platform
import subprocess
import Queue
import threading
def worker_func(pingArgs, pending, done):
try:
while True:
# Get the next address to ping.
address = pending.get_nowait()
ping = subprocess.Popen(ping_args + [address],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
out, error = ping.communicate()
# Output the result to the 'done' queue.
done.put((out, error))
except Queue.Empty:
# No more addresses.
pass
finally:
# Tell the main thread that a worker is about to terminate.
done.put(None)
# The number of workers.
NUM_WORKERS = 4
plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir, 'hosts.txt')
# The arguments for the 'ping', excluding the address.
if plat == "Windows":
pingArgs = ["ping", "-n", "1", "-l", "1", "-w", "100"]
elif plat == "Linux":
pingArgs = ["ping", "-c", "1", "-l", "1", "-s", "1", "-W", "1"]
else:
raise ValueError("Unknown platform")
# The queue of addresses to ping.
pending = Queue.Queue()
# The queue of results.
done = Queue.Queue()
# Create all the workers.
workers = []
for _ in range(NUM_WORKERS):
workers.append(threading.Thread(target=worker_func, args=(pingArgs, pending, done)))
# Put all the addresses into the 'pending' queue.
with open(hosts, "r") as hostsFile:
for line in hostsFile:
pending.put(line.strip())
# Start all the workers.
for w in workers:
w.daemon = True
w.start()
# Print out the results as they arrive.
numTerminated = 0
while numTerminated < NUM_WORKERS:
result = done.get()
if result is None:
# A worker is about to terminate.
numTerminated += 1
else:
print result[0] # out
print result[1] # error
# Wait for all the workers to terminate.
for w in workers:
w.join()Context
StackExchange Code Review Q#13683, answer score: 5
Revisions (0)
No revisions yet.