6
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
ealeon
  • 11,288
  • 20
  • 84
  • 159
  • You can't. Programs don't ask for input; they wait for it. – zondo Mar 02 '16 at 15:23
  • how do i know if they are waiting for it.... (ask/wait) i dont see the difference – ealeon Mar 02 '16 at 15:24
  • 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. – zondo Mar 02 '16 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? – ealeon Mar 02 '16 at 15:30
  • @zondo i want to be able to do something like the edited section – ealeon Mar 02 '16 at 15:31
  • You might find the [pexpect](https://pexpect.readthedocs.org/en/stable/) module useful. – zondo Mar 02 '16 at 15:32
  • You would have to write to stdin and parse from stdout – Padraic Cunningham Mar 02 '16 at 15:34
  • 1
    You can check the waiting channel in `/proc//wchan` or you can trace the subprocess with `ptrace`/`strace`/whatever you like. – Andrea Corbellini Mar 02 '16 at 15:45
  • here's [code example for a "dialog-based interaction" with a child process using `subprocess` and `pexpect`](http://stackoverflow.com/q/7897202/4279). You should try to import the module instead of running it as a subprocess: put the code into functions and call them in the parent, [example](http://stackoverflow.com/q/30076185/4279) – jfs Mar 02 '16 at 19:41

1 Answers1

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
Padraic Cunningham
  • 168,988
  • 22
  • 228
  • 312
  • 1
    Thank you! This is what I am looking for – ealeon Mar 02 '16 at 19:52
  • 1
    @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 `write`s 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 Mar 03 '16 at 12:15