1

I have just started learning Python and stuck with the following issue. I have a simple program to read ip addresses from a text file and check the ICMP reachability. I don't have issue with the program when there is a single IP address in the text file, however, as soon I add more than 1 IP address in the text file , my program doesn't work. It looks like with more than 1 address, windows ping utility is not even able to understand the IP addresses and tries to resolve name.

Sample code to read the file and check ICMP:

def  validate_ip():
    global ip_add_list

     check = False


    while True:
        try:

            ip_file = raw_input("Enter the file name and extension:")
            selected_ip_file = open(ip_file,'r')
            selected_ip_file.seek(0)
            ip_add_list = selected_ip_file.readlines()
            selected_ip_file.close()

        #print ip_add_list
        except IOError:
            print"*File %s doesn't exist, try again" % ip_file
            continue
    check2 = False
    while True:
        for ip in ip_add_list:
           print ip
           ping_reply = subprocess.call(['ping','-n','5','-w','1000','-a',ip])
           if ping_reply == 0:
               check2 = True
               print "pings completed"


           else:
               check2 = False
               break
    if check2 == True:
        break
    elif check2 == False:
        print"Some or all ip(s) in the file are not reachable, please check and try again"
        validate_ip()

I have a simple text file with the following addresses.

4.2.2.2

8.8.8.8

I can ping these addresses from command prompt ,however not from the program.

This is the errors i get while pinging from the program.

Ping request could not find host 4.2.2.2 . Please check the name and try again. Some or all ip(s) in the file are not reachable, please check and try again

(Looks like it doesn't understand that 4.2.2.2 is already an IP)

As soon I remove the second address from the text file and run again , I am able to ping to 4.2.2.2.

roadrunner66
  • 7,772
  • 4
  • 32
  • 38
  • 1
    You might have a newline appended to each IP address. In the `subprocess.call` try `ip.rstrip()`. – cdarke Apr 17 '16 at 16:28
  • @cdarke Wow! worked like charm. This was driving me crazy. Appreciated the help cdarke. Is there a way to provide kudos for help? – Python_Noob Apr 17 '16 at 19:38
  • I'm glad to help, your thanks are enough. This kind of problem is common when using text read from a file, so I have seen it before with filenames rather than IP addresses. A tip: you had a `print ip` trace statement, when you do that then use something like `print '<'+ip+'>'`. The chevrons show if there is any whitespace around. Same goes when embedding variables inside error messages. – cdarke Apr 18 '16 at 06:23
  • Also, error messages should go to `stderr`. For example :`print >> sys.stderr, "*File <%s> doesn't exist, try again" % ip_file`. BTW, there are other reasons why you can't open a file, permissions for example. You are assuming that it doesn't exist without interrogating the `IOError` exception. – cdarke Apr 18 '16 at 06:30
  • All you need there is: `except IOError, err:` followed by: `print >> sys.stderr, err, "Try again"`. The system supplied error message is usually enough. – cdarke Apr 18 '16 at 06:39
  • @Python_Noob: If cdarke's comment helped you, but he doesn't write an answer, why don't you write it as answer and accept it. That is acceptable practice and will help others who have the same problem. The answer I provided used that same concept in `line(rstrip('\n')` – roadrunner66 Apr 19 '16 at 16:14
  • @cdarke thank you for the great explanation. I am just learning Python and hope to learn and share more through this community. – Python_Noob Apr 20 '16 at 05:48
  • @Python_Noob: to clarify, I didn't put it as an answer because I took a quick look at the code and guessed. It was the `readlines()` that gave it away. I only post answers when I can reproduce the problem and the fix. – cdarke Apr 20 '16 at 06:38

2 Answers2

1

Due to white spaces in the file, IP address was not identified valid in the program. Thanks to cdarke for providing the solution below.

"You might have a newline appended to each IP address. In the subprocess.call try ip.rstrip()"

roadrunner66, I also appreciate your help with this issue and providing the solution.

0

Note :This question is likely a duplicate of ping-a-site-in-python.

To make code readable turn it into chunks like the ones below. Credit to python-read-file-line-by-line-into-array. The SO question ping-a-site-in-python also discusses alternative ways to ping.

import subprocess

def validate_ips_from_file(filename):
    lines = [line.rstrip('\n') for line in open('filename')]
    validate_ips(lines)

def validate_ips(ipaddresses):
        for ip in ipaddresses:
            ping_reply=validate_ip(ip)
            print ip, ping_reply

def validate_ip(ipaddress):
    ping_reply = subprocess.call(['ping','-c','5','-w','1000','-a',ipaddress])
    #https://en.wikipedia.org/wiki/Ping_(networking_utility)    
    return ping_reply

validate_ips(['www.nytimes.com','www.theregister.co.uk','www.stackoverflow.com'])

output:

www.nytimes.com 1
www.theregister.co.uk 1
www.stackoverflow.com 1
Community
  • 1
  • 1
roadrunner66
  • 7,772
  • 4
  • 32
  • 38