number12
number12

Reputation: 55

stdout/stderr tuples or string output

I have some code, it's a standard command to stdout.

params = [toolsDir + "\\adb.exe", "shell", "pm", "path", app]
p = Popen(params, shell=False, stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
    if "package:" in stdout:
         package = stdout[8:].rstrip()

Line 3, returns a string, as Line 5 then works successfully without error, I can split and rstrip() on 'package'.

 stdout, stderr = p.communicate()

However... if I remove 'stderr' from Line 3, so it ends up as

stdout = p.communicate() 

I get the error:

    package = stdout[8:].rstrip()
AttributeError: 'tuple' object has no attribute 'rstrip'

Can someone explain why this happens, as stderr isn't even being defined to a pipe on Line 2 Popen, so why does it return a tuple without stderr, but a string with it?

I have already fixed this problem, albeit, it took me a good 30 minutes, and now wish to know why it matters. Thanks.

Upvotes: 4

Views: 1051

Answers (2)

wap26
wap26

Reputation: 2290

communicate returns a tuple

So you can either unpack it on-the-fly (like in your first version):

stdout, stderr = p.communicate()

or you can get the tuple as-is (like is your modified code):

stdout = p.communicate() # tuple with 'stdout' and 'stderr'

I you want to drop stderr, you can write:

stdout = p.communicate()[0]

Upvotes: 3

Yu Hao
Yu Hao

Reputation: 122383

This simpler example could help you understand what is going on:

>>> a, b = (1,2)
>>> a
1
>>> b
2

If b is removed, then:

>>> a = (1,2)
>>> a
(1, 2)

a is assigned the value of the whole tuple, which is not what you want.

Upvotes: 1

Related Questions