0

I have hit another "wall"... I have the following script, which appears to work fine on Windows, however when I move it to Linux it seems to lose functionality.

Note: I added the print line(s) statements for troubleshooting.

The following script outputs the contents of the hostsFile when I print lines, and then prints each line in turn when I print line. But when it reaches the ping execution, it appears to jump straight to the last host in the file. I was wondering if I have missed something clearly obvious (I am still learning python as a newbie).

import sys, os, platform, subprocess

plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir,'hosts.txt')
hostsFile = open(hosts, "r")
lines = hostsFile.readlines()
print lines
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

elif plat == "Linux":
        for line in lines:
                print line
                line = line.strip()
                ping = subprocess.Popen(
                        ["ping", "-c", "1", "-s", "1", "-l", "1",line],
                        stdout = subprocess.PIPE,
                        stderr = subprocess.PIPE
                )
        out, error = ping.communicate()
        print out
        print error

hostsFile.close()

Any thoughts/help is appreciated.

Many thanks in advance.

Regards,

MHibbin

EDIT: Thanks to Wooble for the help... the correct code should be (notice the spacing):

import sys, os, platform, 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", line],
                        stdout = subprocess.PIPE,
                        stderr = subprocess.PIPE
                )
                out, error = ping.communicate()
                print out
                print error

hostsFile.close()
3
  • 1
    You call communicate outside the for loop, so you should expect it to only communicate once. This is not the code you're running on Windows if you're not seeing the same behavior. Commented May 17, 2012 at 11:23
  • @Wooble, that's the one!.... forgot python is spacing sensitive. Commented May 17, 2012 at 11:37
  • You should also make sure that ping is in the path, or give the full path to it, and that the user executing the script has rights to execute ping. Commented May 17, 2012 at 11:46

3 Answers 3

1

This code, as shown, will not work on Windows or Linux. You need to move ping.communicate() inside your loop, otherwise it will execute only once the loop has completed.

Your for loop should read like this:

for line in lines:
    print line
    line = line.strip()
    ping = subprocess.Popen(
                ["ping", "-c", "1", "-s", "1", "-l", "1",line],
                stdout = subprocess.PIPE,
                stderr = subprocess.PIPE
          )
    out, error = ping.communicate()
    print out
Sign up to request clarification or add additional context in comments.

Comments

0

I believe this is what you're after:

import sys, os, platform, subprocess

plat = platform.system()
scriptDir = sys.path[0]
hosts = os.path.join(scriptDir,'hosts.txt')
hostsFile = open(hosts, "r")
lines = hostsFile.readlines()
print lines
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

elif plat == "Linux":
        for line in lines:
                print line
                line = line.strip()
                ping = subprocess.Popen(
                        ["ping", "-c", "1", "-s", "1", "-l", "1",line],
                        stdout = subprocess.PIPE,
                        stderr = subprocess.PIPE
                )
                out, error = ping.communicate()
                print out
                print error

hostsFile.close()

Note the increased indents for the print statements, which should be in the for loops. I have just tried this on my machine and it is printing out a ping for each result in hosts.txt - I assume this is what you wanted?

Comments

0

The problem is that you are calling communicate only once after the for loop. At that point in the script, the variable ping references the last call to subprocess from the loop.

You can experience that with an empty "hosts.txt" file. You won't get into the loop even once, so you'll get a NameError: NameError: name 'ping' is not defined

You should call that inside the loop!

UPDATE: Example:

for line in lines:
    print line
    line = line.strip()
    ping = subprocess.Popen(
        ["ping", "-c", "1", "-s", "1", "-l", "1",line],
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE
    )
    out, error = ping.communicate()
    print "out:", out
    print "error:", error

2 Comments

do you mean I should call hostsFile = open(hosts, "r") inside the loop?
no you should call ping.communicate() inside the loop and print the output there too, I'll show you how.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.