Python script to ping hosts from a file and write to another file

Hi Experts,

I have written a python script that pings all of the hosts in a file called hosts.txt.  The script has been written using Python 2.7 for Windows.

The script will show the output on the screen and also write the results onto a file called ping.txt.

The script has been working fine, but strangely today it has been showing the following error:

Traceback (most recent call last):
  File "sitebenchmark.py", line 46, in <module>
    minimum = str(re.findall(r"Minimum = (\d+)", out)[0])
IndexError: list index out of range

Here is the code I have written (I am fairly new to Python)

import sys
import subprocess
import re
import itertools
import os
import platform

print "\n"
print "-----------"
print " PING TEST"
print "-----------"
print "\n"

plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir, 'hosts.txt')
hostsFile = open(hosts, "r")
lines = hostsFile.readlines()

print ("Checking for existing file:  ping.txt \n")
if os.path.exists('ping.txt'):
    os.remove('ping.txt')
    print ("ping.txt FOUND \n")
    print ("Removing old file:  ping.txt \n")
    print ("Writing clean file:  ping.txt \n")
else:
    print ("Writing new file: ping.txt \n")
print("-------------------------------------")

print("Reading in hosts from hosts.txt \n")


for line in lines:
    line = line.strip( )
    if plat == "Windows":
        args = ["ping", "-n", "4", "-l", "1", "-w", "100", line]

    ping = subprocess.Popen(
        args,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE
    )

    out, error = ping.communicate()

    minimum = str(re.findall(r"Minimum = (\d+)", out)[0])
    maximum = str(re.findall(r"Maximum = (\d+)", out)[0])
    average = str(re.findall(r"Average = (\d+)", out)[0])
    packet = str(re.findall(r"Lost = (\d+)", out)[0])

    f = open('ping.txt', 'a')
    f.write("Hostname:  " + line + "\n")
    f.write("Minumum Response:  " + minimum + "ms" + "\n")
    f.write("Maximum Response:  " + maximum + "ms" + "\n")
    f.write("Average Response:  " + average + "ms" + "\n")
    f.write("Packet Loss:  " + packet + " packets" + "\n")
    f.write("\n")
    f.close()

    print "Hostname:  ", line
    print "Minumum Response:  ", minimum,"ms"
    print "Maximum Response:  ", maximum,"ms"
    print "Average Response:  ", average,"ms"
    print "Packet Loss:  ",packet,"packets"

    print error

hostsFile.close()
print "\n"
print "----------------"
print "SCRIPT COMPLETE"
print "----------------"
print "\n"
print "After confirming results in 'ping.txt', please press ENTER key to exit script"
raw_input()

Open in new window


Can someone help me fix the problem.
madstylexAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Walter RitzelSenior Software EngineerCommented:
The error means that you regular expression object (re) did not found a match for the regular expression 'Minimum = (\d+)'.

The root cause could be the ping command is not working for some reason and it is not producing the expected result.
0
madstylexAuthor Commented:
Thanks Walter,

On further investigation I've discovered that the error comes up on IP addresses that take more than around 550ms to respond, even though the IPs in question are live.

Are you able to give me any ideas on how to solve that?
0
Brett CrawleyZone LeaderCommented:
You need to increase the 100 value line number 36:

args = ["ping", "-n", "4", "-l", "1", "-w", "100", line]

Open in new window


this is the time to wait for the response in ms. Perhaps increase it to 1000ms

args = ["ping", "-n", "4", "-l", "1", "-w", "1000", line]

Open in new window

1
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

madstylexAuthor Commented:
Hi Brett,

This has worked.

On top of that would you be able to show me how to inlcude error handling into the script, so that it prints a message and continues after a non-responsive address?
1
Walter RitzelSenior Software EngineerCommented:
here it is:
import sys
import subprocess
import re
import itertools
import os
import platform
import traceback

print "\n"
print "-----------"
print " PING TEST"
print "-----------"
print "\n"

plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir, 'hosts.txt')
hostsFile = open(hosts, "r")
lines = hostsFile.readlines()

print ("Checking for existing file:  ping.txt \n")
if os.path.exists('ping.txt'):
    os.remove('ping.txt')
    print ("ping.txt FOUND \n")
    print ("Removing old file:  ping.txt \n")
    print ("Writing clean file:  ping.txt \n")
else:
    print ("Writing new file: ping.txt \n")
print("-------------------------------------")

print("Reading in hosts from hosts.txt \n")


for line in lines:
    try:
        line = line.strip( )
        if plat == "Windows":
            args = ["ping", "-n", "4", "-l", "1", "-w", "1000", line]

        ping = subprocess.Popen(
            args,
            stdout = subprocess.PIPE,
            stderr = subprocess.PIPE
        )

        out, error = ping.communicate()

        minimum = str(re.findall(r"Minimum = (\d+)", out)[0])
        maximum = str(re.findall(r"Maximum = (\d+)", out)[0])
        average = str(re.findall(r"Average = (\d+)", out)[0])
        packet = str(re.findall(r"Lost = (\d+)", out)[0])

        f = open('ping.txt', 'a')
        f.write("Hostname:  " + line + "\n")
        f.write("Minumum Response:  " + minimum + "ms" + "\n")
        f.write("Maximum Response:  " + maximum + "ms" + "\n")
        f.write("Average Response:  " + average + "ms" + "\n")
        f.write("Packet Loss:  " + packet + " packets" + "\n")
        f.write("\n")
        f.close()

        print "Hostname:  ", line
        print "Minumum Response:  ", minimum,"ms"
        print "Maximum Response:  ", maximum,"ms"
        print "Average Response:  ", average,"ms"
        print "Packet Loss:  ",packet,"packets"

        print error
    except:
        print 'Error processing line: ', line
        print 'Error message: ', traceback.format_exc()

hostsFile.close()
print "\n"
print "----------------"
print "SCRIPT COMPLETE"
print "----------------"
print "\n"
print "After confirming results in 'ping.txt', please press ENTER key to exit script"
raw_input()

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Filip KrukowskiCommented:
Hi madstylex,

In this script i try to export errors in to file output, but i can't. Do you have any idea how to do this?
0
james andersonCommented:
Hey, I wanted to use your script but in Python 3.x so I converted it using 2to3.py
I then ran the script but was getting the following error

Error processing line:  192.168.27.1
Error message:  Traceback (most recent call last):
  File "C:\Python\Ping\pingscript2.py", line 48, in <module>
    minimum = str(re.findall(r"Minimum = (\d+)", out)[0])
  File "C:\AppData\Local\Programs\Python\Python35-32\lib\re.py", line 213, in findall
    return _compile(pattern, flags).findall(string)
TypeError: cannot use a string pattern on a bytes-like object

After a lot of trial and error (newbie to Python) I fixed the issue and thought I would share in case anybody else wanted a working Python 3 version of the code.

Thanks for the script it is exactly what I was looking for

import sys
import subprocess
import re
import itertools
import os
import platform
import traceback

print("\n")
print("-----------")
print(" PING TEST")
print("-----------")
print("\n")

plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir, 'hosts.txt')
hostsFile = open(hosts, "r")
lines = hostsFile.readlines()

print ("Checking for existing file:  ping.txt \n")
if os.path.exists('ping.txt'):
    os.remove('ping.txt')
    print ("ping.txt FOUND \n")
    print ("Removing old file:  ping.txt \n")
    print ("Writing clean file:  ping.txt \n")
else:
    print ("Writing new file: ping.txt \n")
print("-------------------------------------")

print("Reading in hosts from hosts.txt \n")


for line in lines:
    try:
        line = line.strip( )
        if plat == "Windows":
            args = ["ping", "-n", "4", "-l", "1", "-w", "1000", line]

        ping = subprocess.Popen(
            args,
            stdout = subprocess.PIPE,
            stderr = subprocess.PIPE
        )

        out, error = ping.communicate()

# Had to add this line to get the script to work
        results=str(out)

# Had to amend the following 4 lines to now use results instead of out as the string to search
        minimum = str(re.findall(r"Minimum = (\d+)", results)[0])
        maximum = str(re.findall(r"Maximum = (\d+)", results)[0])
        average = str(re.findall(r"Average = (\d+)", results)[0])
        packet = str(re.findall(r"Lost = (\d+)", results)[0])
       
        f = open('ping.txt', 'a')
        f.write("Hostname:  " + line + "\n")
        f.write("Minumum Response:  " + minimum + "ms" + "\n")
        f.write("Maximum Response:  " + maximum + "ms" + "\n")
        f.write("Average Response:  " + average + "ms" + "\n")
        f.write("Packet Loss:  " + packet + " packets" + "\n")
        f.write("\n")
        f.close()

        print("Hostname:  ", line)
        print("Minumum Response:  ", minimum,"ms")
        print("Maximum Response:  ", maximum,"ms")
        print("Average Response:  ", average,"ms")
        print("Packet Loss:  ",packet,"packets")

         
        print(error)
    except:
        print('Error processing line: ', line)
        print('Error message: ', traceback.format_exc())

hostsFile.close()
print("\n")
print("----------------")
print("SCRIPT COMPLETE")
print("----------------")
print("\n")
print("After confirming results in 'ping.txt', please press ENTER key to exit script")
input()
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Python

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.