Understanding Popen.communicate Understanding Popen.communicate python python

Understanding Popen.communicate


.communicate() writes input (there is no input in this case so it just closes subprocess' stdin to indicate to the subprocess that there is no more input), reads all output, and waits for the subprocess to exit.

The exception EOFError is raised in the child process by raw_input() (it expected data but got EOF (no data)).

p.stdout.read() hangs forever because it tries to read all output from the child at the same time as the child waits for input (raw_input()) that causes a deadlock.

To avoid the deadlock you need to read/write asynchronously (e.g., by using threads or select) or to know exactly when and how much to read/write, for example:

from subprocess import PIPE, Popenp = Popen(["python", "-u", "1st.py"], stdin=PIPE, stdout=PIPE, bufsize=1)print p.stdout.readline(), # read the first linefor i in range(10): # repeat several times to show that it works    print >>p.stdin, i # write input    p.stdin.flush() # not necessary in this case    print p.stdout.readline(), # read outputprint p.communicate("n\n")[0], # signal the child to exit,                               # read the rest of the output,                                # wait for the child to exit

Note: it is a very fragile code if read/write are not in sync; it deadlocks.

Beware of block-buffering issue (here it is solved by using "-u" flag that turns off buffering for stdin, stdout in the child).

bufsize=1 makes the pipes line-buffered on the parent side.


Do not use communicate(input=""). It writes input to the process, closes its stdin and then reads all output.

Do it like this:

p=subprocess.Popen(["python","1st.py"],stdin=PIPE,stdout=PIPE)# get output from process "Something to print"one_line_output = p.stdout.readline()# write 'a line\n' to the processp.stdin.write('a line\n')# get output from process "not time to break"one_line_output = p.stdout.readline() # write "n\n" to that process for if r=='n':p.stdin.write('n\n') # read the last output from the process  "Exiting"one_line_output = p.stdout.readline()

What you would do to remove the error:

all_the_process_will_tell_you = p.communicate('all you will ever say to this process\nn\n')[0]

But since communicate closes the stdout and stdin and stderr, you can not read or write after you called communicate.


Your second bit of code starts the first bit of code as a subprocess with piped input and output. It then closes its input and tries to read its output.

The first bit of code tries to read from standard input, but the process that started it closed its standard input, so it immediately reaches an end-of-file, which Python turns into an exception.