如何写入python中使用fork()获得的子进程stdin?

Vas*_*lis 1 python fork

好吧,我需要写一个用fork()获得的子进程的stdin.我还需要将stdin的文件描述符(?)保留到父进程以重复写入child.我os.pipe()用来获取描述符,所以请保持这种方式.

pid = fork()
if pid == 0:
    os.write(sys.stdin.fileno(), "sample") # <-- isn't this the child's stdin?
    os.execv(..)
    .
    .
Run Code Online (Sandbox Code Playgroud)

子进程是一个bash脚本,如:

#!/bin/bash
/usr/bin/mplayer -slave "$1" <&0
Run Code Online (Sandbox Code Playgroud)

显然,我想使用slave从其stdin接收命令的模式使用python控制mplayer

fork()是必不可少的,因为程序的结构,所以请不要使用communicate等等

aba*_*ert 5

你想做的事情是不可能的,因为它没有意义.子节点与父节点具有相同的标准输入,而不是您可以写入的新节点.POSIX保证fork:

子进程应拥有自己父文件描述符的副本.每个子文件描述符应引用与父文件的相应文件描述符相同的打开文件描述.


与此同时,你正试图从孩子内部写下孩子的标准.这更没意义.你期望写自己的stdin做什么?


当然,孩子可以写入自己的标准输出,这将与父母的标准输出相同.但我怀疑这不是你想要的.你想要的是父母写给孩子的标准差.

如果是这样,你必须在分叉之前创建一个管道,然后用该管道的读取端替换子项的stdin(通常使用dup2),然后写入该管道的写入侧.在CPython的subprocess实现是如何做到这一点,而无需依赖于更高级的功能(即使它在C,而不是在Python)很好的例子代码.

像这样的东西:

pr, pw = pipe()
pid = fork()
if pid == 0:
    os.close(pw)
    sys.stdin.close()
    os.dup2(pr, 0)
    os.execv(...)
else:
    os.close(pr)
    os.write(pw, "sample")
Run Code Online (Sandbox Code Playgroud)