有人可以解释一下为什么我想要的结果“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' 并不会出现。
有人可以解释一下为什么我想要的结果“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' 并不会出现。
b
表示你拥有的是bytes
,它是一系列字节的二进制序列,而不是Unicode字符的字符串。子进程输出的是字节而不是字符,这就是communicate()
返回的内容。
bytes
类型不能直接被print()
输出,因此你看到的是bytes
的repr
。如果你知道从子进程接收到的字节的编码方式,你可以使用decode()
将它们转换为可打印的str
:
>>> print(b'hi\n'.decode('ascii'))
hi
>>> 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'
os.popen
返回文本字符串时,是否有办法使subprocess.Popen
也返回它们,而不是字节字符串。 - Pavel ŠimerdaPopen
对象接受和返回文本字符串。 - Pavel Šimerdacheck_output("dir")
,从输出中提取文件名,然后尝试使用open
访问该文件将失败,如果文件名包含德语umlauts。这可能是一个错误。建议修复。 - kdb如之前提到的,echo hi
实际上会返回 hi\n
,这是一种预期的行为。
但你可能只想以“正确”的格式获取数据,而不需要处理编码。你只需向 subprocess.Popen()
传递 universal_newlines=True
选项即可:
>>> import subprocess
>>> print(subprocess.Popen("echo hi",
shell=True,
stdout=subprocess.PIPE,
universal_newlines=True).communicate()[0])
hi
这样,Popen()
将自行替换这些不需要的符号。
universal_newlines=True
起到了神奇的作用。依我之见,这应该成为被采纳的答案。 - Ethan StriderPopen
中需要使用 universal_newlines=True
(以消除 b''
)并在结果字符串上使用 strip()
。 - arielf默认情况下,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
以下代码将仅打印输出数据。
import subprocess
print(subprocess.Popen("echo hi", shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())
echo hi
会打印出hi\r\n
。为了避免这种情况,你可以在末尾添加.strip()
或类似的修复方法。 - azhreicheck_output()
代替.communicate()
:print(subprocess.check_output("echo hi", shell=True, universal_newlines=True), end="")
。 - jfs