Wizard
Wizard

Reputation: 22113

subprocess.Popen.communicate return a tuple unexceptedly

I am practicing the subprocess operations with the following commands:

In [1]: import subprocess
In [3]: cp = subprocess.Popen("cat /etc/group", shell=True, stdout=subprocess.PIPE, stderr=sub
   ...: process.PIPE).communicate()
In [4]: cp
Out[4]: 
(b'root:x:0:\nbin:x:1:\ndaemon:x:2:\nsys:x:3:\nadm:x:4:\ntty:x:5:\ndisk:x:6:\nlp:x:7:\nmem:x:8:\nkmem:x:9:\nwheel:x:10:\ncdrom:x:11:\nmail:x:12:postfix\nman:x:15:\ndialout:x:18:\nfloppy:x:19:\ngames:x:20:\ntape:x:30:\nvideo:x:39:\nftp:x:50:\nlock:x:54:\naudio:x:63:\nnobody:x:99:\nusers:x:100:\nutmp:x:22:\nutempter:x:35:\nssh_keys:x:999:\ninput:x:998:\nsystemd-journal:x:190:\nsystemd-network:x:192:\ndbus:x:81:\npolkitd:x:997:\npostdrop:x:90:\npostfix:x:89:\nchrony:x:996:\nsshd:x:74:\nntp:x:38:\ntcpdump:x:72:\nnscd:x:28:\nnginx:x:995:\nstapusr:x:156:\nstapsys:x:157:\nstapdev:x:158:\ntss:x:59:\nmysql:x:27:\ntest:x:1000:\nscreen:x:84:\n',
 b'')

When I tried to decode it:

In [5]: out = cp.stdout.read().decode("utf-8")
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-5-4f20648dd0bc> in <module>()
----> 1 out = cp.stdout.read().decode("utf-8")

AttributeError: 'tuple' object has no attribute 'stdout'

Tried alternatively

In [6]: out = cp.decode("utf-8")
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-6-853060f6d163> in <module>()
----> 1 out = cp.decode("utf-8")

AttributeError: 'tuple' object has no attribute 'decode'

How could it return a tuple? I follow step by step the answer python - Hold the output of subprocess.Popen with a arbitrary varible - Stack Overflow

Upvotes: 3

Views: 1977

Answers (1)

iBug
iBug

Reputation: 37307

Sorry it was my fault. I made a mistake in my answer to the question you linked.

The return value of Popen.communicate() is a tuple that contains the stdout and stderr, so you want to pick the one you want:

cp[0].decode('utf-8')  # cp[1] if you want stderr

Another way is to remove .communicate() and read the program output:

proc = Popen("cat /etc/group", shell=True, stdout=subprocess.PIPE)
out = proc.stdout.read().decode("utf-8") 

Upvotes: 5

Related Questions