views:

165

answers:

3

Given this :

import os
import subprocess

def check_server():

    cl = subprocess.Popen(["nmap","10.7.1.71"], stdout=subprocess.PIPE)
    result = cl.communicate()
    print result

check_server()

check_server() returns this tuple:

('\nStarting Nmap 4.53 ( http://insecure.org ) at 2010-04-07 07:26 EDT\nInteresting ports on 10.7.1.71:\nNot shown: 1711 closed ports\nPORT   STATE SERVICE\n21/tcp open  ftp\n22/tcp open  ssh\n80/tcp open  http\n\nNmap done: 1 IP address (1 host up) scanned in 0.293 seconds\n', None)

Changing the second line in the method to

result, err = cl.communicate()

results in check_server() returning :

Starting Nmap 4.53 ( http://insecure.org ) at 2010-04-07 07:27 EDT
Interesting ports on 10.7.1.71:
Not shown: 1711 closed ports
PORT   STATE SERVICE
21/tcp open  ftp
22/tcp open  ssh
80/tcp open  http

Nmap done: 1 IP address (1 host up) scanned in 0.319 seconds

Looks to be the case that the tuple is converted to a string, and the \n's are being stripped.... but how?

+5  A: 

cl.communicate() is still returning a tuple. The assignment result, err = ... has the effect of unpacking the tuple into the variables result (a string) and err (an integer).

When you print the tuple, it uses the repr(...) of each element, but when you print the string, it just prints the string, hence the absence of delimiters and \ns.

Marcelo Cantos
+1  A: 

print is clever. If you pass it a string, it just prints it. If you pass it something else (a tuple in this example) then it prints it's representation (as returned by repr()).

The representation of a string has \n where the string contains newlines. The representation also has quotes around it.

Try changing your print statement to print repr(result) and you'll see.

user9876
`print` doesn't use `__repr__()` if `__str__()` is available, but standard sequence types do use `__repr__()` for printing their elements.
Bastien Léonard
+3  A: 

In both cases cl.communicate() returns a two-element tuple (stdout and stderr of the command if both stdout and stderr are redirected to a PIPE). In first case you assign this tuple to the result variable. When you print it you get a text representation of the tuple. Special characters, like end-of-line are escaped (to '\n') in such representation.

In the second case you unpack the tuple. This means: you assign the first element of the tuple to result and the second to err. As the result is already a string it is printed with no escaping – end-of-line characters are displayed as line breaks and not '\n'.

Jacek Konieczny
+1 - good explanation as well
CaseyIT