Question

I am have to capture output of tshark -D using python subprocess. Here is tshark -D output,

$ tshark -D 1. eth0 2. any (Pseudo-device that captures on all interfaces) 3. lo And using python it gives,

>>> import subprocess
>>> p = subprocess.Popen(["tshark", "-D"], stdout=subprocess.PIPE) ###1
>>> 1. eth0
2. any (Pseudo-device that captures on all interfaces)
3. lo
>>> p = subprocess.Popen(["tshark", "-D"], stderr=subprocess.PIPE,stdout=subprocess.PIPE) ###2
>>> p.stderr.read()
'1. eth0\n2. any (Pseudo-device that captures on all interfaces)\n3. lo\n'
>>> p.stdout.read()
''

In #1, after entering command it gives output. And in #2, required output comes in stderr. Why is it giving results like this ?

Was it helpful?

Solution

To get all output whether the subprocess prints on stdout or stderr, you could use stderr=STDOUT and subprocess.check_output:

from subprocess import check_output, STDOUT

all_output = check_output(['tshark', '-D'], stderr=STDOUT)

tshark manual says:

-D Print a list of the interfaces on which TShark can capture, and exit.

It doesn't specify that the output must be on stderr. Though on my system it prints the diagnostic information only to stderr. Stdout might be reserved for printing captured data.

OTHER TIPS

tshark -D always prints to stderr. In case #1, since you did not capture the stderr, it is printed to your console.

In case #2, since you capture both stdout and stderr, stdout ==> '' and stderr ==> the output.

For # 1: Because you have not process the standard pipe and output, so the print out of the command will just print there in the screen. When you want to process the standard pipe, you need both process the stdout and stderr. Otherwise you actually cannot capture the standard pipe. When you specify a standard pipe, you should handle the standard error print out at the same time.

It's more like this below, if you have a function under the module named "func_my.py":

def func_my():
    print "Hello"
    return "World"

if __name__ == "__main__":
    func_my()

When you call this function, if you don't process the console output, the string "hello" will be directly show in the console output.

p = subprocess.Popen(["python", "func_my.py"], stdout=subprocess.PIPE)

This will always print the "hello".

For #2: You do capture the standard output and error put, but you have made a mistake. You have put all the pipe to both stdout and stderr. The right way should bwlow:

p = subprocess.Popen(["tshark", "-D"], stderr=subprocess.STDOUT,stdout=subprocess.PIPE)
p.stderr.read()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'read'
p.stdout.read()
"WARNING: gnome-keyring:: couldn't connect to: /tmp/keyring-UBTaGc/pkcs11: No such file or directory\ntshark: There are no interfaces on which a capture can be done\n"

Hope will hep you!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top