简体   繁体   English

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

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

I have to files, main.py and child.py . 我必须要文件main.pychild.py

I am trying to send a string to the stdin of main.py . 我正在尝试向main.py的stdin发送一个字符串。

This is my incomplete code: 这是我不完整的代码:

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

I have no idea how to do this. 我不知道该怎么做。

I am running windows 10 with python 3.5.1 我正在使用python 3.5.1运行Windows 10

-Thanks -谢谢

EDIT: When I am sending the argument back to main.py, I can not re-open the program. 编辑:当我将参数发送回main.py时,我无法重新打开程序。 os.system re-opens the program which is not useful in my case. os.system重新打开该程序,对我而言这没有用。

These programs are a small demo of what I am trying to do. 这些程序只是我要尝试做的一个小演示。 In my actual program, I am not able to do that as the two programs are "communicating" with each other an need to be open at all times. 在我的实际程序中,我无法做到这一点,因为这两个程序彼此“通信”,需要始终保持打开状态。

What I need answered is a way to send an argument to main.py perhaps using stdin but when I am sending my argument, It can not re-open the program. 我需要回答的是一种可能使用stdin将参数发送到main.py的方法,但是当我发送参数时,它无法重新打开程序。 Some examples like os.system re-open the program which is not what I am trying to do. 像os.system这样的例子重新打开了程序,这不是我想要的。 I need main.py open at all times. 我需要一直打开main.py。

I have my new current code which is not working. 我有新的当前代码不起作用。 A window pops up and then closes. 弹出窗口,然后关闭。

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

That is my code. 那是我的代码。

What you need is something along the lines of (in main.py ): 您所需要的是(在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()

You're assuming child.exe (in your mockup demo, python.exe ) is communicating with main.py via sys.stdin/stdout , however these I/O's are used to communicate with the shell that spawned the process. 您假设child.exe (在您的模型演示python.exe )正在通过sys.stdin/stdoutmain.py进行通信,但是这些I / O用于与产生该过程的shell进行通信。

Much like the childs stdout/stdin will be communicating with the shell that spawned that process, in this case Popen() . 就像孩子的stdout/stdin将与产生该进程的shell通信一样,在本例中为Popen()

Each spawned child process of subprocess.Popen(...) will be isolated with it's own stdout/stdin/stderr , otherwise every subprocess would make a huge mess of your main process stdout/stdin. 每个子进程subprocess.Popen(...)产生的子进程都将使用其自己的stdout/stdin/stderr进行隔离,否则每个子进程都会对您的主进程stdout / stdin造成极大的混乱。 This means you'll have to check for output on that particular subprocess and write to it accordingly as done in the above example. 这意味着您必须检查该特定子进程的输出,并按照上面的示例进行相应的写入。

One way to look at it is this: 一种查看方式是: 在此处输入图片说明

You're starting main.py , and you communicate with it via sys.stdout and sys.stdin . 您正在启动main.py ,并通过sys.stdoutsys.stdin通信。 Each input() in main.py will output something to sys.stdout so you can read it. main.py每个input()都会向sys.stdout输出一些内容,以便您可以读取它。

Exactly the same logic applies to child.exe where every input() will output something to it's sys.stdout (- But remember - sys is not a shared variable across processes) . 正是同样的逻辑也适用于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()

But a simple print(1) would do the same because it will essentially output the 1 to sys.stdout for you. 但是,简单的print(1)会执行相同的操作,因为它将本质上为您将1输出到sys.stdout

Edit 2018: Don't forget to close your inputs and outputs, as they might leave open file descriptors on your file system, hogging resources and causing problems later in life. Edit 2018:不要忘记关闭输入和输出,因为它们可能会在文件系统上留下打开的文件描述符,从而浪费资源并在以后的生活中造成问题。

Other conveyers of information 其他信息传达者

Assuming you have control of the code to child.exe and you can modify the communication pipe in any way, some other options are: 假设您可以控制child.exe的代码,并且可以以任何方式修改通信管道,则其他一些选项包括:

More cautionary tails! 更多警示尾巴!

  • .readline() will assume there's a \\n somewhere in your data, most likely at the end. .readline()将假设您的数据中某处有一个\\n ,最有可能在结尾处。 I switched to .readline() for two reasons, .read() will hang and wait for EOF unless you specify exactly how many bytes to read, if I'm not out on a bicycle. 我切换到.readline()的原因有两个, .read()会挂起并等待EOF除非您确切指定要读取的字节数(如果我没有骑自行车的话)。 To be able to read all kinds of output you need to incorporate select.select() into your code - or a buffer of some sort where you call x.stdout.read(1) to read one byte at a time. 为了能够读取所有类型的输出,您需要将select.select()合并到代码中,或者将某种形式的缓冲区合并到其中,您可以在其中调用x.stdout.read(1)读取一个字节。 Because if you try to read .read(1024) and there's not 1024 bytes in the buffer, your read will hang until there are 1024 characters. 因为如果您尝试读取.read(1024)并且缓冲区中没有1024字节,则读取将挂起,直到有1024个字符为止。

  • I left a bug in your child.py code on purpose (mine works) - It's trivial and basic Python - in hopes that it's a learning experience on how to debug errors (you mentioned you're not good at it, this is a way to learn). child.py在您的child.py代码中留下了一个错误(我的作品有效)-它是简单而基本的Python-希望这是关于如何调试错误的学习经验(您提到自己并不擅长,这是一种方法学习)。

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

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