Here I can ping each IP but am not able to extract the Average of the result. Can anyone help, please?
import subprocess
import threading
ip_list = []
def ping(host):
ip_list.append(host ' ' str((subprocess.run('ping ' host ' -n 1').returncode)))
with open(r'input.txt', "r") as input_file:
hosts = input_file.read()
hosts_list =hosts.split('\n')
num_threads = 1
number = 0
while number< len(hosts_list):
for i in range(num_threads):
t = threading.Thread(target=ping, args=(hosts_list[number i],))
t.start()
t.join()
number = number 1
CodePudding user response:
After doing some research I found out that using subprocess.run and then getting the returncode you dont get the output but only the return code so usually 0 for a successfull run with no error. If you want to get the output of the process you have to use subprocess.Popen and then communicate. Then if you only want the average you have to do some string manipulation with the output to only get the number after "Average". Here's an exemple:
def ping(host):
output = subprocess.Popen(["ping", host, "-n", "1"], stdout=subprocess.PIPE).communicate()[0]
words = str(output).split(sep=" ")
average = words[words.index("Average") 2].split("ms")[0]
ip_list.append(host ' ' average)
CodePudding user response:
If you call ping with '-c 1' then the total duration of execution of the subprocess will be a very close approximation to the actual ping duration.
Therefore you could just do this:
from concurrent.futures import ThreadPoolExecutor
import subprocess
import time
FILENAME = 'hosts.txt'
def main():
with open(FILENAME) as hosts:
with ThreadPoolExecutor() as executor:
threads = list(executor.map(process, map(str.strip, hosts)))
if threads:
print(f'Average ping duration = {sum(threads)/len(threads):.4f}')
else:
print('No threads executed. Empty file?')
def process(host):
command = f'ping -c 1 -n {host} >/dev/null 2>&1'
start = time.perf_counter()
try:
subprocess.run(command, shell=True, check=True)
except Exception:
pass
return time.perf_counter() - start
if __name__ == '__main__':
main()
CodePudding user response:
As suggested by @Miguel Pereira, I made a few changes. In this code, however, all of the results are not appended to the results file. Only the last IP response can be written to the results file. Any suggestions would be appreciated. The results filename is timestamped.
import subprocess
import threading
import time
timestr = time.strftime("%Y-%m-%d %H%M%S")
timesec = time.strftime("%Y-%m-%d %H:%M:%S")
raw_list = []
def ping(host):
results_file = open("results" str(timestr) ".txt", "w")
p = subprocess.Popen(["ping", host, "-n", "1"], shell=True, universal_newlines=True, stdout=subprocess.PIPE)
response = p.communicate()[0]
for i in response.split("\n"):
para =i.split("=")
try:
if para[0].strip() =="Minimum":
latency =para[3].strip()
onlylatency = list(latency)
latencyfin = onlylatency[0]
except:
print("time run")
if "Received = 1" and "Approximate" in response:
print(f"UP {host} Ping Successful")
results_file.write(f"{host},UP,{latencyfin},{timesec}" "\n")
else:
print(f"Down {host} Ping Unsuccessful")
results_file.write(f"{host},Down,0,{timesec}" "\n")
results_file.close()
with open(r'input.txt', "r") as server_list_file:
hosts = server_list_file.read()
hosts_list =hosts.split('\n')
num_threads = 1
number = 0
while number< len(hosts_list):
# print(number)
for i in range(num_threads):
t = threading.Thread(target=ping, args=(hosts_list[number i],))
t.start()
t.join()
number = number 1