我发现以下行为非常令人困惑:
Python 3.7.2 (default, Feb 12 2019, 08:15:36)
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> import sys
>>> sys.stdout.write(b'')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: write() argument must be str, not bytes
>>> subprocess.run('echo', stdout=sys.stdout)
CompletedProcess(args='echo', returncode=0)
sys.stdout
不接受二进制。我没有在subprocess
调用中指定编码,这意味着它应该是流二进制的。在这种情况下,子进程如何知道不提供文件对象二进制数据?
答案 0 :(得分:3)
您误会了子流程的工作方式。子进程不会与sys.stdout
对象进行交互-该对象仅存在于python中,并且仅存在于您的过程中。
要了解实际情况,您首先需要知道操作系统如何处理IO。在操作系统级别,每个打开的文件(或管道)都分配有一个ID-称为file handle。例如,stdout
的句柄通常是数字1
:
>>> sys.stdout.fileno()
1
启动子流程时,仅将此文件句柄传递给子流程。子进程没有不能访问sys.stdout
文件对象。子进程可以做的就是将字节写入接收到的文件句柄。 (在操作系统级别,只有字节,没有文本。)您不能强制子进程使用特定的编码。
当您将encoding
参数传递给subprocess.run
时,该编码仅用于编码发送到子流程或从子流程接收的文本。它不会影响子流程本身,只会影响您的流程与子流程的通信方式。