Python Output Displaying Horizontal

I feel bad for posting so much lately. I've just been working on a project for fun to force myself to learn Python better. Recently I decided to incorporate this ping.py script on github found here. I'm not going to bore you with all the changes I made, but the problem now lies in this function from ping.py here:

def verbose_ping(dest_addr, timeout=2, count=4):

    global response

    for i in range(count):
        delay = do_one(dest_addr, timeout)
        if delay == None:
            f = open(os.devnull,"w")
        else:
            delay = round(delay * 1000.0, 4)
            response = ('{}'.format(dest_addr))

Then there's my code which calls the ping.py code:

#!/usr/bin/python

import re
import ping, socket
import subprocess
from subprocess import Popen, PIPE

pattern = re.compile(r'inet.\S+(\S+\d+\.\d+\.\d+\.)')

p1 = Popen(["/sbin/ifconfig"], stdout=subprocess.PIPE)

output = p1.communicate()[0]
result = re.findall(pattern, output)

for i in xrange(1, 255):
    test = result[1] + str(i)
    try:
        ping.verbose_ping(test, count=1)
    except socket.error, e:
        print "Ping Error:", e

for item in ping.response:
    print item

I should have had 10.0.0.1 and 10.0.0.139 displaying, but after waiting for the output to process I only got one ip address and it came out horizontal:

# ./sundayadd.py 
1
0
.
0
.
0
.
1
3
9

I've been going at this for most of today and I think my eyes are going to bleed again. If anyone has a suggestion while I unplug for a while its much appreciated.

use printf instead of print

1 Like

I actually just found I could get the output straight if I put a comma in the last loop:

for item in ping.response:
    print item,

I still only get one ip and using item.replace didn't remove the extra white space. I just tried using printf with the following:

#!/usr/bin/python
import re
import ping, socket
import subprocess
from subprocess import Popen, PIPE

import sys
def printf(format, *args):
    sys.stdout.write(format % args)

pattern = re.compile(r'inet.\S+(\S+\d+\.\d+\.\d+\.)')

p1 = Popen(["/sbin/ifconfig"], stdout=subprocess.PIPE)

output = p1.communicate()[0]
result = re.findall(pattern, output)

for i in xrange(1, 255):
    test = result[1] + str(i)
    try:
        ping.verbose_ping(test, count=1)
    except socket.error, e:
        print "Ping Error:", e

for item in ping.response:
    #print item.replace(" ", "")
    printf('This is a test: %r', item)

While it didn't fix the output, it did provide a clue. It seems the characters of the ip addresses are going in one at a time instead of together:

# ./sundayadd.py 
This is a test: '1'This is a test: '0'This is a test: '.'This is a test: '0'This is a test: '.'This is a test: '0'This is a test: '.'
This is a test: '1'This is a test: '3'This is a test: '9'

Just not sure where this is happening...

When you use ping.response in a for-loop, it returns an iterator over which the loop iterates. I don't have the ping module in my python installation, so I cannot test it. But try one of the following:

print "This is a test: " + str(ping.response)

or

printf("This is a test: ")
for item in ping.response:
    printf("%r", item)

If the former solution works, I would recommend you to use that over the latter one.

Sorry I'm just now getting back to this. Had a long day with a shift change for new training at work. I ran the two suggestions:

First:

# ./monday.py 
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139
This is a test: 10.0.0.139

Second:

# ./monday.py 
This is a test: '1''0''.''0''.''0''.''1''3''9'

Looks like this confirms my suspicion that the ip addresses are being broken into characters somewhere. I guess its overwriting the list with each new ip's characters. The 10.0.0.139 is the last on that subnet. It seems the first code also iterated ten times and there are ten characters in 10.0.0.139 if you count the dots. Still at a loss for where this is coming from though.

Thanks again for the suggestions.

Try:

print "{0}".format(''.join(item))

Just woke up and tried this:

for item in ping.response:
    print "{0}".format(''.join(item))

Seems to go horizontal again:

# ./monday.py 
1
0
.
0
.
0
.
1
3
9

Let's see if I can hammer something new out before work.

Try this logic:

#!/usr/bin/python

import re
import ping, socket
import subprocess
from subprocess import Popen, PIPE

pattern = re.compile(r'inet.\S+(\S+\d+\.\d+\.\d+\.)')

p1 = Popen(["/sbin/ifconfig"], stdout=subprocess.PIPE)

output = p1.communicate()[0]
result = re.findall(pattern, output)

ips_ok = []

for i in xrange(1, 255):
    test = result[1] + str(i)
    try:
        ping.verbose_ping(test, count=1)
    except socket.error, e:
        print "Ping Error:", e
    else:
        ips_ok.append(test)

for ip in ips_ok:
    print ip
1 Like

Didn't see this had gone into a second page for a while. That worked Klashxx! Thank you. I thought I had tried the .append before, I guess I was not implementing that correctly. Much appreciated.