在python3中发送到程序的标准输入 [英] Sending to the stdin of a program in python3
问题描述
我必须存档,main.py 和 child.py.
我正在尝试向 main.py 的标准输入发送一个字符串.
I am trying to send a string to the stdin of 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
I am running windows 10 with python 3.5.1
-谢谢
当我将参数发送回 main.py 时,我无法重新打开程序.os.system 重新打开了对我来说没有用的程序.
When I am sending the argument back to main.py, I can not re-open the program. os.system re-opens the program which is not useful in my case.
这些程序是我正在尝试做的事情的一个小演示.在我的实际程序中,我无法做到这一点,因为这两个程序相互通信",需要始终打开.
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.
我需要回答的是一种可能使用 stdin 向 main.py 发送参数的方法,但是当我发送参数时,它无法重新打开程序.像 os.system 这样的一些例子重新打开程序,这不是我想要做的.我需要一直打开 main.py.
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. Some examples like os.system re-open the program which is not what I am trying to do. I need main.py open at all times.
我的当前新代码不起作用.一个窗口弹出然后关闭.
I have my new current code which is not working. A window pops up and then closes.
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
中):
What you need is something along the lines of (in 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
)正在通过 与
,但是这些 I/O 用于与产生进程的 shell 进行通信.main.py
通信>sys.stdin/stdout
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.
很像孩子的 stdout/stdin
将与产生该进程的 shell 进行通信,在这种情况下是 Popen()
.
Much like the childs stdout/stdin
will be communicating with the shell that spawned that process, in this case Popen()
.
subprocess.Popen(...)
的每个衍生子进程都将与它自己的 stdout/stdin/stderr
隔离,否则每个子进程都会弄得一团糟您的主进程标准输出/标准输入.这意味着您必须检查该特定子进程的输出,并按照上面的示例进行相应的写入.
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. 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:
您正在启动 main.py
,并通过 sys.stdout
和 sys.stdin
与它通信.main.py
中的每个 input()
都会向 sys.stdout
输出一些内容,以便您阅读.
You're starting main.py
, and you communicate with it via sys.stdout
and sys.stdin
. Each input()
in main.py
will output something to sys.stdout
so you can read it.
完全相同的逻辑适用于 child.exe
,其中每个 input()
都会输出一些东西到它的 sys.stdout
(- 但请记住 - sys
不是跨进程的共享变量).
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).
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
.
But a simple print(1)
would do the same because it will essentially output the 1
to sys.stdout
for you.
Edit 2018:不要忘记关闭您的输入和输出,因为它们可能会在您的文件系统上留下打开的文件描述符,占用资源并在以后的生活中引起问题.
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.
假设您可以控制 child.exe
的代码并且您可以以任何方式修改通信管道,那么其他一些选项是:
Assuming you have control of the code to child.exe
and you can modify the communication pipe in any way, some other options are:
- 套接字 - 使用常规套接字进行通信,在 *nix 上最有效的是 Unix 套接字.
- 可以在此处找到其他一些解决方案:从 Python 脚本返回值的最佳方法
.readline()
会假设数据中有一个\n
,很可能在最后.我切换到.readline()
有两个原因,.read()
将挂起并等待EOF
除非您指定确切的字节数阅读,如果我不骑自行车.为了能够读取各种输出,您需要合并 select.select() 进入您的代码 - 或某种缓冲区,您可以在其中调用x.stdout.read(1)
一次读取一个字节.因为如果您尝试读取.read(1024)
并且缓冲区中没有 1024 个字节,您的读取将挂起直到有 1024 个字符.
.readline()
will assume there's a\n
somewhere in your data, most likely at the end. I switched to.readline()
for two reasons,.read()
will hang and wait forEOF
unless you specify exactly how many bytes to read, if I'm not out on a bicycle. 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 callx.stdout.read(1)
to read one byte at a time. 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.
我故意在你的 child.py
代码中留下了一个错误(我的作品)——它是微不足道的基本 Python——希望它是关于如何调试错误的学习经验(你提到你不擅长,这是一种学习方式).
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).
这篇关于在python3中发送到程序的标准输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!