1

I'm having problems reading/writing to stdin/stdout in a child process with subprocess.communicate().

This is the child process (in C)

#include <stdio.h>

int main ()
{
    char buf[128];
    printf("test\n");
    gets(buf);
    printf("%s", buf);
    return 0;
}

This is the program in python that calls that child program

import subprocess

proc = subprocess.Popen('./test', stdin=subprocess.PIPE, stdout=subprocess.PIPE)

stdin, stderr = proc.communicate()
print stdin
proc.communicate(stdin)
stdin, stderr = proc.communicate()
print stdin

print stdin

I would expect this to print

test
input was test:

However, it seems that proc.communicate() causes an EOF for gets(), causing the child application to terminate. Is there anyway I can communicate with the child application without sending an EOF? IE I would like to read to the application AND THEN write to it.

endeavormac
  • 659
  • 2
  • 8
  • 18
  • I accepted the answer below because it was very important to finding the solution to my problem. I also wanted to add that I needed a `fflush(stdout);` as input was being buffered and this was causing issues. – endeavormac Feb 22 '12 at 20:38

1 Answers1

1

From the documentation for Popen.communicate():

Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate.

This means that you can only call communicate() once for your subprocess.

Getting real time output can be kind of tricky, but in your example it shouldn't be too difficult since you are only attempting to read a single line. The following should work:

import subprocess

proc = subprocess.Popen('./test', stdin=subprocess.PIPE, stdout=subprocess.PIPE)

outdata = proc.stdout.readline()
print outdata
outdata, errdata = proc.communicate('output was ' + outdata)
print outdata

Note that I renamed some of your variables, since the output from your subprocess is not really stdin for your Python process.

Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
  • +1. You might also decided not to use communicate() at all. For an example, see http://stackoverflow.com/questions/9322796/keep-a-subprocess-alive-and-keep-giving-it-commands-python/9327923#9327923 – user9876 Feb 22 '12 at 19:50
  • Is it possible to wait on command which we pass to communicate? Example: i have cmd1, cmd2, cmd3 as commands passed to communicate. Can i wait for 5s after each command execution? – user6882413 Aug 08 '20 at 22:39