views:

41

answers:

1

I'm trying to pipe input to a program opened as a subprocess in Python. Using communicate() does what I want, but it only does so once, then waits for the subprocess to terminate before allowing things to continue.

Is there a method or module similar to communicate() in function, but allows multiple communications with the child process?

Here's an example:

import subprocess

p = subprocess.Popen('java minecraft_server.jar',
                 shell=True,
                 stdin=subprocess.PIPE);

//Pipe message to subprocess' console here

//Do other things

//Pipe another message to subprocess' console here

If this can be done in an easier fashion without using subprocess, that would be great as well.

+1  A: 

You can write to p.stdin (and flush every time to make sure the data is actually sent) as many separate times as you want. The problem would be only if you wanted to be sure to get results back (since it's so hard to convince other processes to not buffer their output!-), but since you're not even setting stdout= in your Popen class that's clearly not a problem for you. (When it is a problem, and you really need to defeat the other process's output buffering strategy, pexpect -- or wexpect on Windows -- are the best solution -- I recommend them very, very often on stackoverflow, but don't have the URLs at hand right now, so pls just search for them yourself if, contrary to your example, you do have that need).

Alex Martelli
Thanks a lot for the answer. I have one question, though. I currently have two separate places in which I write to p.stdin and flush it, but it seems to wait until the second of those two before sending, instead of sending them separately at their respective times. Also, the second message is appended on the end. Maybe I'm misunderstanding the use of flush() here.
Sean O'Hollaren
@Sean, the second "message" should indeed come right after the first, if that's what you mean by "appended on the end". But the problem is that there is no concept of "message" on a pipe (such as, standard input) -- it's a _stream_, **not** a queue of messages. Most "text-mode interactive" programs read (and act on) one line from their standard input at a time -- is this the strategy being followed by your target subprocess, and, if so, are you properly sending the line termination character at the end of each of your "messages"? Or, what other strategy does that process use?
Alex Martelli
Not terminating the line is _exactly_ what I was doing wrong. Thanks so much for the help.
Sean O'Hollaren
@Sean, you're welcome!
Alex Martelli