发送到 python3 中程序的标准输入

Sending to the stdin of a program in python3

我必须归档,main.pychild.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

我不知道该怎么做。

我是 运行 windows 10 和 python 3.5.1

-谢谢

编辑: 当我将参数发送回 main.py 时,我无法重新打开程序。 os.system 重新打开对我来说没有用的程序。

这些程序是我正在尝试做的事情的一个小演示。在我的实际程序中,我无法做到这一点,因为这两个程序彼此 "communicating" 需要始终打开。

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

我的新代码无法正常工作。弹出一个window然后关闭

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()

这是我的代码。

您需要的是(在 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)正在通过 sys.stdin/stdoutmain.py 通信,但是这些 I/O用于与生成进程的 shell 通信。

很像 childs stdout/stdin 将与产生该进程的 shell 进行通信,在本例中为 Popen().

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

一种查看方式是这样的:

您正在启动 main.py,您通过 sys.stdoutsys.stdin 与其通信。 main.py 中的每个 input() 都会向 sys.stdout 输出一些内容,以便您阅读。

完全相同的逻辑适用于 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 - 希望这是一个关于如何调试的学习经验错误(你提到你不擅长,这是一种学习方式)。