简体   繁体   English

如何将 2 个输入写入 python 子进程

[英]How can I write 2 input to python subprocess

I am trying to use subprocess library.我正在尝试使用子进程库。

The file that I am trying to run with subprocess:我试图用子进程运行的文件:

a = input()
print(a)

Here is what I tried:这是我尝试过的:

import subprocess

p = subprocess.Popen(['python', 'registration.py'], encoding="Utf8")
p.communicate(input="11")

It worked very well.它工作得很好。 Then I tried to use multiple inputs:然后我尝试使用多个输入:

a=input()
print(a)
b=input()
print(b)

I used 2 p.communicate(input='something') but got an error in the second one: ValueError: I/O operation on closed file.我使用了 2 p.communicate(input='something')但在第二个中出现错误: ValueError: I/O operation on closed file.

I surfed the Internet and found that communicate only works once.我在网上冲浪,发现communicate只能工作一次。

My question is, is there a way to give 2 inputs to subprocess in my case?我的问题是,在我的情况下,有没有办法为子流程提供 2 个输入?

Here is the full code这是完整的代码

import subprocess
from subprocess import PIPE

p = subprocess.Popen(['python', '-i', 'registration.py'], stdin=PIPE, text=True)

p.stdin.reconfigure(line_buffering=True)
p.stdin.write("phone_number\n")
#I should wait here for maximum 15 seconds
p.stdin.write("verification_code\n")
print("Done")
#First, Done is printed, console says program finished but then subprocess methods are executed

If you create the Popen object with stdin=subprocess.PIPE , it has a stdin attribute that you can write to.如果您使用stdin=subprocess.PIPE subprocess.PIPE 创建Popen object ,则它具有您可以写入的stdin属性。

However, the subrocess documentation warns that this can lead to deadlocks:但是, subrocess文档警告说这可能导致死锁:

due to any of the other OS pipe buffers filling up and blocking the child process.由于任何其他操作系统 pipe 缓冲区填满并阻塞子进程。

If you write small amounts of data and if the subprocess reads its standard input regularly, it should be fine.如果您写入少量数据并且子进程定期读取其标准输入,那应该没问题。

An example:一个例子:

> python
Python 3.9.13 (main, May 31 2022, 12:56:40) 
[Clang 13.0.0 (git@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a on freebsd13
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess as sp
>>> proc = sp.Popen(['python', '-i'], stdin=sp.PIPE, text=True)
>>> Python 3.9.13 (main, May 31 2022, 12:56:40) 
[Clang 13.0.0 (git@github.com:llvm/llvm-project.git llvmorg-13.0.0-0-gd7b669b3a on freebsd13
Type "help", "copyright", "credits" or "license" for more information.
>>> proc.stdin.write("1+2\n")
4
>>> proc.stdin.flush()
>>> 3
>>> proc.stdin.write("3*9\n")
4
>>> proc.stdin.flush()
>>> 27
>>> proc.stdin.reconfigure(line_buffering=True)
>>> proc.stdin.write("3*12\n")
5
>>> 36
>>> proc.kill()
>>> 

Of note:注意:

  • Multiple programs need to be told to be interactive if their standard input is not a terminal.如果多个程序的标准输入不是终端,则需要告知它们是交互式的。 Hence the use of the '-i' flag.因此使用'-i'标志。
  • Use text=True to make your life easier.使用text=True让您的生活更轻松。
  • Note that if line_buffering is not activated for a standard input of the subprocess, you have to flush the stream for the process to receive the data.请注意,如果没有为子进程的标准输入激活line_buffering ,则必须刷新 stream 以便进程接收数据。
  • Therefore it is probably best to reconfigure the stdin stream of the Popen object and set line_buffering to True .因此,最好重新配置 Popen object 的stdin Popen并将line_buffering设置为True

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

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