Cry2Senpai Cry2Senpai - 3 years ago 136
Python Question

How to get Popen to write to a file

So I've made and IP/Hostname scanner and I'm trying to get the output to print to a file after it runs the ping or fails to run the ping. My problem is I get these errors:

Traceback (most recent call last):
File ".\IPlookup.py", line 59, in <module>
print >> IPtext," is down!", 'Filename:', filename
AttributeError: 'str' object has no attribute 'write'

Traceback (most recent call last):
File ".\IPlookup.py", line 55, in <module>
print >> output, 'Filename:', filename
AttributeError: 'Popen' object has no attribute 'write'


This is what the actual code looks like

#This here code is used to scan IP's hostnames or files and ping them, then if there is 0% packet loss it does an nslookup...

import sys
import os
import subprocess

#This is supposed to print the output to a txt file but boy howdy does it not work

elif userType == '-l':
IPtext = raw_input("Please enter IP or URL: ")
response = os.system("ping -c 1 " + IPtext)
output = subprocess.Popen(['nslookup',IPtext])
if response == 0:
f = open('out.txt','w')
print >> output, 'Filename:', filename
f.close()
else:
f = open('out.txt','w')
print >> IPtext," is down!", 'Filename:', filename
f.close()


Is there a way to get both the str output and the popen to write to a file or do I need to change my code completely?

Solved a portion of my problem by doing this instead

elif userType == '-l':
with open('out.txt','a') as f:
IPtext = raw_input("Please enter IP or URL: ")
response = os.system("ping -c 1 " + IPtext)
output = subprocess.Popen(['nslookup',IPtext])
if response == 0:
f.write(output)
f.close()
else:
f.write(IPtext)
f.close()


The only thing that does not work now is printing out popen which throws the error

TypeError: argument 1 must be string or read-only character buffer, not Popen

elif userType == 't -l' or userType == 't --logfile':
with open('Pass.txt','a') as f:
IPtext = raw_input("Please enter IP or URL: ")
response = os.system("ping -c 1 " + IPtext)
merp = subprocess.Popen(['nslookup',IPtext], stdout=subprocess.PIPE)
out, err = merp.communicate()
if response == 0:
f.write('\n')
f.write(out)
f.close()
else:
with open('Fail.txt','a') as f:
f.write('\n')
f.write(IPtext)
f.close()

Answer Source

If I understand your problem correctly, the line of f.write(output) throws the TypeError.

This is the case because output is a Popen-object in your case. Replace these lines:

output = subprocess.Popen(['nslookup',IPtext])
    if response == 0:
        f.write(output)

with these:

# ... everything before your .subprocess.Popen(...) line
popen = subprocess.Popen(['nslookup',IPtext], stdout=subprocess.PIPE)# this is executed asynchronus
popen.wait() # this is to wait for the asynchron execution
resultOfSubProcess, errorsOfSubProcess = popen.communicate()
# resultOfSubProcess should contain the results of Popen if no errors occured
# errorsOfSubProcess should contain errors, if some occured
    if response == 0:
        f.write(resultOfSubProcess)
        # ... the rest of your code

Edit: You might also want to check against an empty resultOfSubProcess variable or errors in errorsOfSubProcess before continuing

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download