在python3中发送到程序的stdin

时间:2016-06-01 05:51:24

标签: python python-3.x stdin

我需要文件, main.py child.py

我正在尝试将字符串发送到 main.py 的标准输入。

这是我不完整的代码:

main.py

from subprocess import *
import time

def main():
    program = Popen(['python.exe'. 'child.py', 'start'])
    while True: #waiting for'1' to be sent to the stdin
        if sys.stdin == '1':
            print('text)

if __name__ == '__main__':
    main()

child.py

import sys

if sys.argv[1] == 'start':
    inp = input('Do you want to send the argument?\n').lower()
    if inp == 'no':
        sys.exit()
    elif inp == 'yes':
        #Somehow send '1' to the stdin of 1.py while it is running

我不知道该怎么做。

我正在使用python 3.5.1运行Windows 10

-Thanks

编辑: 当我将参数发送回main.py时,我无法重新打开该程序。 os.system重新打开在我的情况下无用的程序。

这些程序是我想要做的一个小型演示。在我的实际计划中,我无法做到这一点,因为这两个程序是"沟通"彼此需要随时开放。

我需要回答的是一种向main.py发送参数的方法,也许是使用stdin但是当我发送我的参数时,它无法重新打开程序。像os.system这样的例子重新打开程序,这不是我想要做的。我需要随时打开main.py.

我有新的当前代码无效。弹出一个窗口然后关闭。

main.py

from subprocess import Popen, PIPE, STDOUT
x = Popen(['python.exe', '2.py', 'start'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
while x.poll() is None:
    if b'Do you want to send the argument?' in x.stdout.read():
        x.stdin.write(b'yes\n')

child.py

import sys
import time
time.sleep(1)
if 1 = 1:
    inp = input('Do you want to send the argument?\n').lower()
    if inp == 'no':
        sys.exit()
    elif inp == 'yes':
        sys.stdout.write('1')
        sys.stdout.flush()

这是我的代码。

1 个答案:

答案 0 :(得分:6)

您需要的是(main.py)中的内容:

from subprocess import Popen, PIPE, STDOUT
x = Popen(['some_child.exe', 'parameter'], stdout=PIPE, stdin=PIPE, stderr=STDOUT)

while x.poll() is None:
    child_output = x.stdout.readline()
    print(child_output)
    if b'Do you want to send the argument?' in child_output:
        x.stdin.write(b'yes\n')
        x.stdin.flush()
x.stdout.close()
x.stdin.close()

您假设child.exe(在您的模型演示中,python.exe)正在通过main.pysys.stdin/stdout进行通信,但是这些I / O用于与产生过程的shell。

就像孩子stdout/stdin将与产生该过程的shell进行通信一样,在这种情况下Popen()

subprocess.Popen(...)的每个衍生子进程都将与它自己的stdout/stdin/stderr隔离,否则每个子进程都会使你的主进程stdout / stdin大错。这意味着您必须检查该特定子进程的输出并相应地写入,如上例所示。

一种看待它的方法是: enter image description here

您正在main.py开始,并通过sys.stdoutsys.stdin与之进行通信。 input()中的每个main.py都会向sys.stdout输出一些内容,以便您阅读。{/ p>

完全相同的逻辑适用于child.exe,其中每个input()都会输出一些内容sys.stdout ( - 但请记住 - sys不是共享变量进程)

import sys

if sys.argv[1] == 'start':
    inp = input('Do you want to send the argument?\n').lower()
    if inp == 'no':
        sys.exit()
    elif inp == 'yes':
        #Somehow send '1' to the stdin of 1.py while it is running
        sys.stdout.write('1')
        sys.stdout.flush()

但是一个简单的print(1)会做同样的事情,因为它基本上会为你输出1sys.stdout

编辑2018:不要忘记关闭输入和输出,因为它们可能会在文件系统上留下打开的文件描述符,占用资源并在以后的生活中造成问题。

其他信息传达者

假设您已将代码控制为child.exe并且您可以以任何方式修改通信管道,则其他一些选项是:

更警惕的尾巴!

  • .readline()会假设数据中某处有\n,最有可能在最后。我切换到.readline()有两个原因,.read()会挂起并等待EOF,除非您指定要读取多少字节,如果我不骑自行车。为了能够读取所有类型的输出,您需要将select.select()合并到代码中 - 或者某种类型的缓冲区,您可以调用x.stdout.read(1)一次读取一个字节。因为如果您尝试读取.read(1024)并且缓冲区中没有1024个字节,则读取将挂起,直到有1024个字符。

  • 我故意在你的child.py代码中留下了一个错误(我的作品) - 这是微不足道的基本Python - 希望这是一个关于如何调试错误的学习经验(你提到你不是擅长,这是一种学习方式。)