Ahmed M.
Ahmed M.

Reputation: 49

Writing Python Script`s Results into Text file

I am trying to write my below pinging script results into a Text file, but i got an error message.

Below is my code:

import os
import time
import subprocess


# Open file for saving ping results
results_file = open("results.txt", "w")

with open('ip-source.txt') as IPs:
    hosts = IPs.read()
    hosts = hosts.splitlines()
    for ip in hosts:
        os.system('cls')
        print('Printing now:', ip)
        print('-'*60)
        result = os.system('ping -n 4 {}'.format(ip))
        print('-'*60)
        time.sleep(1)

with open("output.txt", "w", encoding="utf8") as output:
    output.write("\n".join([post.text for post in result]))

and when i ran it i got below error message:

Traceback (most recent call last):
File "script.py", line 21, in <module>
output.write("\n".join([post.text for post in result]))
TypeError: 'int' object is not iterable

Upvotes: 0

Views: 1126

Answers (2)

tripleee
tripleee

Reputation: 189427

Probably better to open the output file once, then have each of the subprocesses append to it as you go.

with open('ip-source.txt') as IPs, open("output.txt", "w") as output:
    for ip in IPs:
        subprocess.run(
            ['ping', '-n', '4', ip.rstrip('\n')],
            stdout=output, text=True, check=True)

Notice also how this avoids invoking a shell at all.

You could streamline this slightly by opening the output file as binary; then you can take out the text=True and let the file accept raw bytes (even though they are eventually going to be parsed as Unicode strings by whatever reads the text file subsequently).

In Python 3, a subprocess returns bytes by default; you then have to decode those bytes into a str (once you know their encoding); or you can specify text=True to have Python transparently encode and decode all these bytes as strings, using the default encoding (UTF-8 on any adult system; YMMV on Windows).

Upvotes: 1

M Z
M Z

Reputation: 4799

os.system returns the exit signal (typically 0 or 1) from the process called. If you look, os.system is actually just a wrapper function for subprocess.Popen.

You'll want to a) use something like subprocess.Popen or subprocess.check_output and then b) add results to a list:

import subprocess
...
results = []
for ip in hosts:
    ...
    results.append(str(subprocess.check_output(["ping", "-n", "4", str(ip)])))

with open("output.txt", "w", encoding="utf8") as output:
    output.writelines(results)

Upvotes: 1

Related Questions