为什么 Popen.Communication()返回 b‘ hi’而不是 hi?

有人能解释一下为什么我想要的结果“ hi”前面有一个字母“ 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”

110197 次浏览

The echo command by default returns a newline character

相比之下:

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

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

bytes类型不能直接使用 print()able,因此您将看到 bytesrepr。如果您知道从子进程收到的字节的编码,您可以使用 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'

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

下面将只打印结果数据

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

如前所述,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()将自己替换这些不需要的符号。