【发布时间】:2020-07-08 01:48:23
【问题描述】:
目标是在 Python 中将一些数据(几个字节)从子进程传递到父进程(不能使用 stdout 和 stderr)。下面是它的简化版本(实际代码在阻塞子进程之前从管道中读取所有数据)。
import os
import subprocess
import sys
CHILD_SCRIPT = r'''
import os
os.write({wfd}, b'Hello, World!')
'''
rfd, wfd = os.pipe()
if hasattr(os, 'set_inheritable'):
os.set_inheritable(wfd, True)
subprocess.check_call([sys.executable, '-c', CHILD_SCRIPT.format(wfd=wfd)])
print(os.read(rfd, 1024))
在 Unix 上,它适用于 Python 2,但不适用于 Python 3,它会失败并显示:
Traceback (most recent call last):
File "<string>", line 3, in <module>
OSError: [Errno 9] Bad file descriptor
Traceback (most recent call last):
File "test_inherit_fd.py", line 13, in <module>
subprocess.check_call([sys.executable, '-c', CHILD_SCRIPT.format(wfd=wfd)])
File "/usr/lib/python3.8/subprocess.py", line 364, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['/bin/python3', '-c', "\nimport os\nos.write(5, b'Hello, World!')\n"]' returned non-zero exit status 1.
显然,失败与FD是否可继承无关。在 Python 3.2(默认情况下 FD 仍可继承)上,它以同样的方式失败。还有什么导致差异的? (编辑:原因是,从 Python 3.2 开始,默认关闭 2 以上的 FD。通过close_fds=False 可以解决问题。
在 Windows 上,它在 Python 2 和 Python 3 上失败。
在所有平台上的 Python 2 和 Python 3 上,将数据(几个字节)从子级传递到父级的稳健且干净的方式是什么?
【问题讨论】:
标签: python subprocess file-descriptor