Question

I'm trying to run a program that requires successive interactions (I have to answer with strings: '0' or '1') from within my python script.

My code:

from subprocess import Popen, PIPE

command = ['program', '-arg1', 'path/file_to_arg1']

p = Popen(command, stdin=PIPE, stdout=PIPE)
p.communicate('0'.encode())

The last two lines work for the first interaction, but after that the program prints all the following questions on the screen without waiting for their respective inputs. I basically need to answer the first question, wait until the program deals with it and prints the second question, then answer the second question, and so on.

Any ideas? Thanks!

PS: I'm using Python 3.3.4

Was it helpful?

Solution

The subprocess module is designed for single-use interactions. Print to a process and read the result, and then STOP. It is challenging to do a ongoing back-and-forth interaction with a Unix process, where you continue to take turns reading and writing. I recommend using a library built for the task, instead of rewriting all the necessary logic from scratch.

There is a classic library named Expect, which works well for interacting with a child process. There is a python implementation named Pexpect (read the docs here). I recommend using Pexpect, or a similar library.

Pexpect works like this:

# spawn a subprocess.
# then wait for expected output from the child process,
# and send additional commands to the child.

child = pexpect.spawnu('ftp ftp.openbsd.org')
child.expect('(?i)name .*: ')
child.sendline('anonymous')
child.expect('(?i)password')
child.sendline('pexpect@sourceforge.net')
child.expect('ftp> ')
child.sendline('cd /pub/OpenBSD/3.7/packages/i386')
child.expect('ftp> ')

OTHER TIPS

For catching stdout in realtime from subprocess better check from this thread catching stdout in realtime from subprocess

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top