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

如何写入python中使用fork()获得的子进程stdin?,python,fork,Python,Fork,我需要向stdin写入使用fork获得的子进程。我还需要将stdin的文件描述符保留在父进程中,以便重复写入子进程。我使用os.pipe来获取描述符,所以请保持这种方式 pid = fork() if pid == 0: os.write(sys.stdin.fileno(), "sample") # <-- isn't this the child's stdin? os.execv(..) . . 子进程是一个bash脚本,类似于: #!/bin/ba

我需要向stdin写入使用fork获得的子进程。我还需要将stdin的文件描述符保留在父进程中,以便重复写入子进程。我使用os.pipe来获取描述符,所以请保持这种方式

pid = fork()
if pid == 0:
    os.write(sys.stdin.fileno(), "sample") # <-- isn't this the child's stdin?
    os.execv(..)
    .
    .
子进程是一个bash脚本,类似于:

#!/bin/bash
/usr/bin/mplayer -slave "$1" <&0
显然,我想用python控制mplayer,它使用从模式接收来自其stdin的命令


由于程序的结构,fork是必不可少的,因此请不要使用communicate等替代方法,因为它没有意义,所以您尝试执行的操作是不可能的。子项与父项具有相同的stdin,而不是可以写入的新stdin。POSIX保证:

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

同时,您试图从孩子的内部向孩子的stdin写信。这就更没有意义了。你希望给自己的stdin写什么

当然,孩子可以写入自己的标准输出,这与父母的标准输出相同。但我怀疑这不是你想要的。您需要的是家长向孩子的stdin写入数据

如果是这样,您必须在分叉之前创建一个管道,然后通常使用dup2将子管道的stdin替换为该管道的读取端,然后写入该管道的写入端。这是一个很好的示例代码,说明了如何在不依赖高级函数的情况下实现这一点,即使它是用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")

你想做的事是不可能的,因为这毫无意义。子项与父项具有相同的stdin,而不是可以写入的新stdin。POSIX保证:

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

同时,您试图从孩子的内部向孩子的stdin写信。这就更没有意义了。你希望给自己的stdin写什么

当然,孩子可以写入自己的标准输出,这与父母的标准输出相同。但我怀疑这不是你想要的。您需要的是家长向孩子的stdin写入数据

如果是这样,您必须在分叉之前创建一个管道,然后通常使用dup2将子管道的stdin替换为该管道的读取端,然后写入该管道的写入端。这是一个很好的示例代码,说明了如何在不依赖高级函数的情况下实现这一点,即使它是用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")

由于程序的结构,我不认为fork是必要的。可能有一些不太清楚的情况,这是真的,不涉及,因为我想做一些非法的事情,在fork和exec之间只有90%的时间有效,每次运行它时我都会祈祷,但我不认为会问这个问题的人会有这样的情况…很抱歉,我们没有你知道的那么多。没有人知道每件事的每一件事,但是如果当人们注意到你缺乏知识而不是试图从中学习时,你会生气,你会发现在任何事情上都很难取得成功。我不可能因为自己缺乏知识而生气,因为我问了!我的评论与你的第一个评论有关,你似乎需要指出某人缺乏知识,而你却讽刺地怀疑这个问题及其参数。毕竟,我怀疑你是否在任何事情上都取得了领先。你要求人们用强硬的方式而不是简单的方式来回答你的问题,并且用相当直截了当的语言来回答。如果你想这样做,你有责任清楚地表明你明白你在说什么,否则大多数人可能会忽略你。你可以抱怨我以这种态度打电话给你,但请注意,我是唯一一个为你回答问题的人;你认为别人是如何接受你的要求的?我不认为fork是必要的,因为程序的结构。可能有一些不太清楚的情况,这是真的,不涉及,因为我想做一些非法的事情,在fork和exec之间只有90%的时间有效,每次运行它时我都会祈祷,但我不认为会问这个问题的人会有这样的情况…很抱歉,我们没有你知道的那么多。没有人知道每件事的每一件事,但是如果当人们注意到你缺乏知识而不是试图从中学习时,你会生气,你会发现在任何事情上都很难取得成功。我不可能因为自己缺乏知识而生气,因为我问了!我的评论与此有关
你的第一个评论,似乎你需要指出某人缺乏知识,而你却讽刺地怀疑这个问题及其参数。毕竟,我怀疑你是否在任何事情上都取得了领先。你要求人们用强硬的方式而不是简单的方式来回答你的问题,并且用相当直截了当的语言来回答。如果你想这样做,你有责任清楚地表明你明白你在说什么,否则大多数人可能会忽略你。你可以抱怨我以这种态度打电话给你,但请注意,我是唯一一个为你回答问题的人;你认为别人是如何接受你的要求的?。。。你根据这句话得出的结论是我不知道我在说什么,这句话有评论!它的评论是问题的一部分。好吧,我把os.write放在那里了——这是错误的——但它不是实际程序的一部分:我不是发布十分之一行代码,而是将问题转换成一种更紧凑的形式,使它更可读,更容易让人理解,就像你一样,你确实理解我试图完成的任务——我不认为你只是猜测而已。问题很清楚。你的代码有效!谢谢你根据这句话得出的结论是我不知道我在说什么,这句话有评论!它的评论是问题的一部分。好吧,我把os.write放在那里了——这是错误的——但它不是实际程序的一部分:我不是发布十分之一行代码,而是将问题转换成一种更紧凑的形式,使它更可读,更容易让人理解,就像你一样,你确实理解我试图完成的任务——我不认为你只是猜测而已。问题很清楚。你的代码有效!谢谢