繁体   English   中英

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

[英]Sending to the stdin of a program in python3

我必须要文件main.pychild.py

我正在尝试向main.py的stdin发送一个字符串。

这是我不完整的代码:

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

-谢谢

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

这些程序只是我要尝试做的一个小演示。 在我的实际程序中,我无法做到这一点,因为这两个程序彼此“通信”,需要始终保持打开状态。

我需要回答的是一种可能使用stdin将参数发送到main.py的方法,但是当我发送参数时,它无法重新打开程序。 像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()

那是我的代码。

您所需要的是(在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进行通信。

就像孩子的stdout/stdin将与产生该进程的shell通信一样,在本例中为Popen()

每个子进程subprocess.Popen(...)产生的子进程都将使用其自己的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)会执行相同的操作,因为它将本质上为您将1输出到sys.stdout

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

其他信息传达者

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

更多警示尾巴!

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

  • child.py在您的child.py代码中留下了一个错误(我的作品有效)-它是简单而基本的Python-希望这是关于如何调试错误的学习经验(您提到自己并不擅长,这是一种方法学习)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM