为什么Popen.communicate()返回b'hi \ n'而不是'hi'?

时间:2013-03-12 23:24:04

标签: python subprocess popen

有人可以解释为什么我想要的结果,“嗨”,前面有一个字母'b',后跟一个换行符?

我正在使用 Python 3.3

>>> import subprocess
>>> print(subprocess.Popen("echo hi", shell=True,
                           stdout=subprocess.PIPE).communicate()[0])
b'hi\n'

如果我使用python 2.7

运行它,则不会出现这个额外的'b'

4 个答案:

答案 0 :(得分:65)

b表示你拥有的是bytes,它是一个二进制的字节序列,而不是一串Unicode字符。子进程输出字节,而不是字符,这就是communicate()返回的内容。

bytes类型不能直接print(),因此您会看到repr bytes的{​​{1}}。如果您知道从子流程收到的字节的编码,则可以使用decode()将它们转换为可打印的str

>>> print(b'hi\n'.decode('ascii'))
hi

当然,这个特定示例仅在您实际从子进程接收ASCII时才有效。如果它不是ASCII,你会得到一个例外:

>>> print(b'\xff'.decode('ascii'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0…

换行符是echo hi输出内容的一部分。 echo的工作是输出您传递的参数,然后输出换行符。如果您对流程输出周围的空白不感兴趣,可以使用strip(),如下所示:

>>> b'hi\n'.strip()
b'hi'

答案 1 :(得分:21)

如前所述,echo hi实际上会返回hi\n,这是预期的行为。

但是你可能只想以“正确”的格式获取数据,而不是处理编码。您需要做的就是将universal_newlines=True选项传递给subprocess.Popen(),如下所示:

>>> import subprocess
>>> print(subprocess.Popen("echo hi",
                           shell=True,
                           stdout=subprocess.PIPE,
                           universal_newlines=True).communicate()[0])
hi

这种方式Popen()将自行替换这些不需要的符号。

答案 2 :(得分:7)

默认情况下,echo命令返回换行符

与此比较:

print(subprocess.Popen("echo -n hi", \
    shell=True, stdout=subprocess.PIPE).communicate()[0])

对于字符串前面的 b ,它表示它是一个字节序列,与Python 2.6 +中的普通字符串相同

http://docs.python.org/3/reference/lexical_analysis.html#literals

答案 3 :(得分:6)

b是字节表示,\ n是echo输出的结果。

以下将仅打印结果数据

import subprocess
print(subprocess.Popen("echo hi", shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())