9
import subprocess

child = subprocess.Popen(['python', 'simple.py'], stdin=subprocess.PIPE)
child.communicate('Alice')

I know you can communicate with executed script via communicate How do you check for whether a script 'simple.py' is asking for user input?

simple.py could ask for 5-10 user inputs so simply hardcoding communicate wouldnt be enough.

[EDIT]: want to parse the stdout as the script is running and communicate back to the script

while True:
    if child.get_stdout() == '?':
       # send user input
9
  • 1
    You can't. Programs don't ask for input; they wait for it. Commented Mar 2, 2016 at 15:23
  • how do i know if they are waiting for it.... (ask/wait) i dont see the difference Commented Mar 2, 2016 at 15:24
  • 1
    You just can't. When it is waiting for input, it is just doing nothing until it gets it. There are many reasons for doing nothing, so there is no way to know that it is waiting specifically for input. Commented Mar 2, 2016 at 15:26
  • well i know at what stdout it is waiting for user input. how do i get stdout as the script prints out then? Commented Mar 2, 2016 at 15:30
  • 1
    You can check the waiting channel in /proc/<pid>/wchan or you can trace the subprocess with ptrace/strace/whatever you like. Commented Mar 2, 2016 at 15:45

1 Answer 1

2

A simple example:

simple.py:

i = raw_input("what is your name\n")
print(i)
j = raw_input("What is your age\n")
print(j)

Read and write:

import subprocess

child = subprocess.Popen(['python2', 'simple.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)

for line in iter(child.stdout.readline, ""):
    print(line)
    if "name" in line:
        child.stdin.write("foo\n")
    elif "age" in line:
        child.stdin.write("100\n")

Output:

what is your name

foo

What is your age

100
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! This is what I am looking for
@ealeon: beware, unless you know exactly how much you should write/read; it is very easy to hang the child process if input/output are out-of-sync (If you try to read too much; you may wait indefinitely for an input that will never come or if you try to write too much then as soon as the corresponding OS pipe buffers are full the writes may block). In general, you should use threads or async. I/O if you are handling more than one pipe (as in this case).
@jfs could you elaborate? Is your comment particularly in the context of the sample code above, being that the child may be waiting for input but won't receive it because the parent loop impacts it somehow? Or is there something else that can "getcha" when using both stdin and stdout pipes together?
@MichaelHarris: my comment is about the general approach (plus/minus unrelated block-buffering issues, the code in the answer may work). Here's code that demonstrate what happens if read/writing are not synchronized perfectly and synchronous read/write are used gist.github.com/zed/dc609d81ce72b3ec9a5619ff0262d889

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.