如何在任何版本的Python中将pipe()描述符传递给Python subprocess.Popen()

时间:2018-02-04 02:19:05

标签: python pipe

我想在Python中生成一个子进程,其标准流用于其他目的,我无法触及它们,我希望有一个专用管道用于我自己的目的,独立于标准流。

在Python版本2中,以下工作:

foobar.py

#!/usr/bin/python

from os import pipe, environ, read
import subprocess

output, input = pipe()
new_environ = environ.copy()
new_environ["PIPE_INPUT"] = str(input)
subprocess.Popen(['./a.out'], env=new_environ)
print(read(output, 6))

a.out是从foobar.c编译的:

#include <unistd.h>
#include <stdlib.h>

void main() {
    write(atoi(getenv("PIPE_INPUT")), "foobar", 6);
}

这有效,./foobar.py打印foobar

但是,有了shebang线

#!/usr/bin/python3

它不起作用。当然,这是因为根据文档,在Python 3中,描述符不可继承。

那么,我如何在Python 3中执行此操作,以及相同的代码适用于Python 2.我不能为不同的Pythons提供不同的代码,必须是Python 2和3的可移植代码。

1 个答案:

答案 0 :(得分:1)

要在必要时使input描述符可继承,请使用

import os

try:
    os.set_inheritable(input, True)
except AttributeError:
    # This is Python 3.3 or older -> Nothing to do
    pass

然后必须将Popen来电修改为

subprocess.Popen(['./a.out'], env=new_environ, close_fds=False)

适用于Python 2和Python 3。