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.
I surfed the Internet and found that communicate
only works once.
My question is, is there a way to give 2 inputs to subprocess in my case?
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.
However, the subrocess
documentation warns that this can lead to deadlocks:
due to any of the other OS pipe buffers filling up and blocking the child process.
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:
'-i'
flag.text=True
to make your life easier.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.stdin
stream of the Popen
object and set line_buffering
to True
.