如何在Python中将数据通过管道传输到os.execv'd进程的标准输入?(涉及IT技术)

3

我想向一个进程的stdin输入一些内容,替换我的当前Python进程。有没有简单的方法可以做到这一点?我在考虑以下方案:

import sys, os

r, w = os.pipe()
os.write(w, 'yo')
os.dup2(r, sys.stdin.fileno())
os.execvp('cat', [''])

但是在我的OS X系统中执行这个命令时,cat命令会卡住,尽管'yo'确实被显示了。为什么呢?

像这样的代码是危险的——如果您将超过一个管道缓冲区大小的数据写入管道(其大小因操作系统等而异),那么您将会造成死锁,因为尚未有读取器来排空管道。 - Adam Rosenfield
那么,我应该如何以安全的方式达成我的目标 -- 不用编写临时文件呢? - verve
1
在执行子进程的execvp()之前,您需要使用os.fork()复制进程;然后父进程向管道中写入数据,而子进程从中读取。父进程必须在fork()之后关闭管道的读取端,而子进程必须将读取端复制到stdin上并在execvp()之前关闭原始管道句柄中的两个。这是标准的Unix管道操作。 - Adam Rosenfield
Adam,如果你还想的话,把你的评论写成答案,我会选择它。从你所写的和我的错误中学到了很多。 - verve
1个回答

4
您在执行子进程的execvp()之前使用os.fork()创建进程;然后父进程向管道中写入数据,子进程从管道中读取。在fork()之后,父进程必须close()管道的读端,子进程必须将读端用dup2()复制到stdin上,并在execvp()之前关闭原始管道句柄。这是标准的Unix管道操作。
例如:
r, w = os.pipe()
if os.fork() == 0:
    # Child process
    os.dup2(r, sys.stdin.fileno())
    os.close(r)
    os.close(w)
    os.execvp(...)
else:
    # Parent process
    os.close(r)
    os.write(w, 'yo')
    ...
    os.close(w)  # When done writing
    os.wait()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接