0

I'm trying to redirect the output of an Nmap scan to a text file using Python.

Here's my code:

outputName = raw_input("What is the output file name?") fname = outputName with open(fname, 'w') as fout: fout.write('') command = raw_input("Please enter an Nmap command with an IP address.") args = shlex.split(command) proc = subprocess.Popen(args,stdout=fname) 

The error:

Traceback (most recent call last): File "mod2hw4.py", line 17, in <module> proc = subprocess.Popen(args,stdout=fname) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 701, in __init__ errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1127, in _get_handles c2pwrite = stdout.fileno() AttributeError: 'str' object has no attribute 'fileno' 
1

2 Answers 2

3

As Paulo mentioned above, you have to pass an open file; the name of the file won't work. You should probably do this with the same context you created (the with block); try rearranging it to this:

outputName = raw_input("What is the output file name?") fname = outputName command = raw_input("Please enter an Nmap command with an IP address.") args = shlex.split(command) with open(fname, 'w') as fout: proc = subprocess.Popen(args,stdout=fout) return_code = proc.wait() 

Not that subprocess.Popen is called with stdout=fout now instead of stdout=fname. The context manager created by the with statement ensures the file will be closed when the nmap process is done, even if an exception occurs.

Sign up to request clarification or add additional context in comments.

2 Comments

note: the file may be closed in the parent before nmap finishes because Popen does not wait for the child process to exit. nmap inherits its own copy of the file descriptor.
@J.F.Sebastian is right - you should explicitly wait for the process to finish first. I've added a call to subprocess.wait to do that in the with block.
1

From the docs:

stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE, an existing file descriptor (a positive integer), an existing file object, and None.

So a filename is not a valid value for the stdout argument.

I guess you want this instead:

proc = subprocess.Popen(args,stdout=open(fname, 'w')) 

Or better yet, just keep everything within the with block:

with open(fname, 'w') as fout: fout.write('') command = raw_input("Please enter an Nmap command with an IP address.") args = shlex.split(command) proc = subprocess.Popen(args,stdout=fout) 

5 Comments

You mean check_output. Agree (there was a since deleted comment about this with a small typo: checked_output).
Thanks so much! I read the description in the documentation but I didn't understand that the name of an open file and a file object weren't the same thing, hence the error. So fout is an actual file object then, just so I'm clear?
Yes, it is. An interesting thing about open files in Python is that they adhere to the "context management protocol", so when you use them at the with statement they are guaranteed to be automatically closed at the end of the block (so your program does not leak resources - most operational systems limit the number of open files)..
I hate to be a bother, but the subprocess with the actual Nmap command isn't executing inside the with block when I run the program. Any ideas?
We are here to help. Inspect the value of proc, may be proc.returncode would give you a clue.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.