Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm using this code to get standard output from an external program:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]

The communicate() method returns an array of bytes:

>>> command_stdout
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n'

However, I'd like to work with the output as a normal Python string. So that I could print it like this:

>>> print(command_stdout)
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2

I thought that's what the binascii.b2a_qp() method is for, but when I tried it, I got the same byte array again:

>>> binascii.b2a_qp(command_stdout)
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n'

Anybody knows how to convert the byte array back to string? I mean, using the "batteries" instead of doing it manually.
And I'd like it to be ok with Python 3.

Thanks!

share|improve this question

4 Answers

up vote 140 down vote accepted

You need to decode the bytes object to produce a string:

>>> b"abcde"
b'abcde'
>>> b"abcde".decode("utf-8")
'abcde'
share|improve this answer
12  
Love you. Thanks! – Tomas Sedovic Mar 3 '09 at 12:30
5  
This 'solution' was particularly hard to find (for me at least) considering it is such a simple problem ... I'd love to put a line somewhere the subprocess docs about this since I bet a good portion of newbies like me will hit this snag when using subprocess. Anybody know about contributing to the python docs? – mathtick Nov 4 '10 at 17:34
Yes, but given that this is the output from a windows command, shouldn't it instead be using ".decode('windows-1252')" ? – mcherm Jul 18 '11 at 19:48
6  
Using "windows-1252" is not reliable either (e.g., for other language versions of Windows), wouldn't it be best to use sys.stdout.encoding? – nikow Jan 3 '12 at 15:20
This is the second time I forgot about this and it’s still nowhere to be found in the documentation, not even in the unicode section. What a shame. – Profpatsch Apr 5 at 10:41
show 2 more comments

You need to decode the byte string and turn it in to a character (unicode) string.

b'hello'.decode(encoding)

or

str(b'hello', encoding)
share|improve this answer

I think what you actually want is this:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>> command_text = command_stdout.decode(encoding='windows-1252')

Aaron's answer was correct, except that you need to know WHICH encoding to use. And I believe that Windows uses 'windows-1252'. It will only matter if you have some unusual (non-ascii) characters in your content, but then it will make a difference.

By the way, the fact that it DOES matter is the reason that Python moved to using two different types for binary and text data: it can't convert magically between them because it doesn't know the encoding unless you tell it! The only way YOU would know is to read the Windows documentation (or read it here).

share|improve this answer

I think easy on this way:

bytes = [112, 52, 52]
"".join(map(chr, bytes))
>> p44
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.