Starting and controlling an external process via STDIN / STDOUT using Python

I need to start an external process that needs to be controlled using messages sent back and forth via stdin and stdout. Using subprocess.Popen I can start the process, but I can not control the execution via stdin, as I need.

The flow of what I'm trying to accomplish is as follows:

  • Start external process
  • Iterate for some steps
    • Tell the external process to complete the next processing step by writing a new stdin
    • Wait until the external process reports that it completed the step by writing a newline on it. stdout
  • Close the external stdin process to indicate the external process that has completed execution.

I got the following:

process=subprocess.Popen([PathToProcess],stdin=subprocess.PIPE,stdout=subprocess.PIPE); for i in xrange(StepsToComplete): print "Forcing step # %s"%i process.communicate(input='\n') 

When I run the above code, '\ n' is not passed to the external process, and I never go beyond step # 0. The blocks of code are on process.communicate () and do not proceed further. Am I using the communication () method incorrectly?

Also, how would I implement β€œwait until the external process writes a new line”, a piece of functionality?

+4
source share
2 answers

process.communicate (input = '\ n') is invalid. If you notice from the Python docs, it writes your string to the stdin of the child, and then reads all the output from the child until the child exits. From doc.python.org:

Popen.communicate (input = None) Interact with the process: sending data to stdin. Read data from stdout and stderr until end-of-file. Wait for the termination process. The optional input argument must be a string to be sent to the child process or Not if no data should be sent to the child.

Instead, you just want to write this child's stdin. Then read it in your loop.

Something else similar:

 process=subprocess.Popen([PathToProcess],stdin=subprocess.PIPE,stdout=subprocess.PIPE); for i in xrange(StepsToComplete): print "Forcing step # %s"%i process.stdin.write("\n") result=process.stdout.readline() 

This will make something more like what you want.

+8
source

You can use Twisted using reactor.spawnProcess and LineReceiver .

0
source

All Articles