.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, Popen

p = Popen(["python", "-u", "1st.py"], stdin=PIPE, stdout=PIPE, bufsize=1)
print p.stdout.readline(), # read the first line
for 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 output

print 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.

Answer from jfs on Stack Overflow
🌐
Python
docs.python.org › 3 › library › subprocess.html
subprocess — Subprocess management
1 week ago - The input argument is passed to Popen.communicate() and thus to the subprocess’s stdin. If used it must be a byte sequence, or a string if encoding or errors is specified or text is true.
Top answer
1 of 3
80

.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, Popen

p = Popen(["python", "-u", "1st.py"], stdin=PIPE, stdout=PIPE, bufsize=1)
print p.stdout.readline(), # read the first line
for 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 output

print 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.

2 of 3
29

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 process
p.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.

People also ask

What does subprocess run do?
Subprocess runs the command, waits for the procedure to complete, and then returns a "Completed process" artifact.
🌐
simplilearn.com
simplilearn.com › home › resources › software development › python subprocess: master external command execution
Python Subprocess: Master External Command Execution
How do you run a subprocess in Python?
If you want to run a Subprocess in python, then you have to create the external command to run it.
🌐
simplilearn.com
simplilearn.com › home › resources › software development › python subprocess: master external command execution
Python Subprocess: Master External Command Execution
Is subprocess a standard Python library?
With the help of the subprocess library, we can run and control subprocesses right from Python.
🌐
simplilearn.com
simplilearn.com › home › resources › software development › python subprocess: master external command execution
Python Subprocess: Master External Command Execution
🌐
Eli Bendersky
eli.thegreenplace.net › 2017 › interacting-with-a-long-running-child-process-in-python
Interacting with a long-running child process in Python - Eli Bendersky's website
July 11, 2017 - Sometimes it's OK to feed this program all its input at once and then check its output; this can, and should be done with communicate - the perfect API for this purpose. It properly feeds stdin, closes it when done (which signals many interactive programs that game's over), etc. But what if we really want to provide additional input based on some previous output of the child process. Here goes: def main(): proc = subprocess.Popen(['python3', '-i'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # To avoid deadlocks: careful to: add \n to output, flush output, use # readline() rather than read() proc.stdin.write(b'2+2\n') proc.stdin.flush() print(proc.stdout.readline()) proc.stdin.write(b'len("foobar")\n') proc.stdin.flush() print(proc.stdout.readline()) proc.stdin.close() proc.terminate() proc.wait(timeout=0.2)
🌐
DataCamp
datacamp.com › tutorial › python-subprocess
An Introduction to Python Subprocess: Basics and Examples | DataCamp
September 12, 2025 - The stdout of the ls command is connected to the stdin of the grep command using subprocess.PIPE, which creates a pipe between the two processes. The communicate() method is used to send the output of the ls command to the grep command and retrieve the filtered output.
🌐
Python Module of the Week
pymotw.com › 2 › subprocess
subprocess – Work with additional processes - Python Module of the Week
Reading from stderr works the same as with stdout. Passing PIPE tells Popen to attach to the channel, and communicate() reads all of the data from it before returning. $ python -u subprocess_popen3.py popen3: pass through: 'through stdin to stdout' stderr : 'to stderr\n'
🌐
Beautiful Soup
tedboy.github.io › python_stdlib › generated › generated › subprocess.Popen.communicate.html
subprocess.Popen.communicate — Python Standard Library
subprocess.Popen.communicate · View page source · Popen.communicate(input=None)[source]¶ · Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent ...
🌐
Real Python
realpython.com › python-subprocess
The subprocess Module: Wrapping Programs With Python – Real Python
January 18, 2025 - By using subprocess, you can execute shell commands like ls or dir, launch applications, and handle both input and output streams. This module provides tools for error handling and process communication, making it a flexible choice for integrating ...
Find elsewhere
🌐
Dcreager
dcreager.net › 2009 › 08 › 06 › subprocess-communicate-drawbacks
dcreager.net – Problems with Python's subprocess.communicate method
It then collects all of the stdout and stderr output from the subprocess, and returns these. The communicate method takes responsibility for avoiding deadlock; it only sends the next chunk of the stdin string when the subprocess is ready to read it, and it only tries to read the next chuck of stdout or stderr when the subprocess is ready to provide it.
🌐
Python 101
python101.pythonlibrary.org › chapter19_subprocess.html
Chapter 19 - The subprocess Module — Python 101 1.0 documentation
In this code example, we create an args variable to hold our list of arguments. Then we redirect standard out (stdout) to our subprocess so we can communicate with it. The communicate method itself allows us to communicate with the process we just spawned. We can actually pass input to the ...
🌐
Simplilearn
simplilearn.com › home › resources › software development › python subprocess: master external command execution
Python Subprocess: Master External Command Execution
December 15, 2025 - Learn about Python's subprocess module for executing external commands. Discover how to manage processes and handle inputs/outputs efficiently.
Address   5851 Legacy Circle, 6th Floor, Plano, TX 75024 United States
🌐
Medium
medium.com › more-python › concurrency-in-python-part-vii-the-subprocess-module-bb54e4134eaa
Concurrency in Python, Part VII — The subprocess Module | by Mikhail Berkov | More Python | Medium
February 9, 2025 - To send input, we simply pass it as an argument to communicate: import subprocess process = subprocess.Popen(["cat"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True) output, _ = process.communicate("Hello, Popen!") print(output) # ...
🌐
Python
docs.python.org › 3 › library › asyncio-subprocess.html
Subprocesses — Python 3.14.4 documentation
February 23, 2026 - See also the Subprocess and Threads section. ... Wait for the child process to terminate. Set and return the returncode attribute. ... This method can deadlock when using stdout=PIPE or stderr=PIPE and the child process generates so much output that it blocks waiting for the OS pipe buffer to accept more data. Use the communicate() method when using pipes to avoid this condition.
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-subprocess-module
Python subprocess module - GeeksforGeeks
2 weeks ago - process.communicate() reads output and waits for completion · check_output() executes a command and returns only its output. If the command fails, it raises an exception. Example: Here, a command is executed and its output is directly returned.
🌐
Reddit
reddit.com › r/learnpython › sending asynchronous input to a constantly-running "subprocess"
r/learnpython on Reddit: Sending asynchronous input to a constantly-running "subprocess"
September 22, 2023 -

Hi everyone,

I am trying to use subprocess.Popen to open Powershell, and from this instance, open a secondary application (such that I can send it asynchronous Powershell commands from my Python code).

However, the subprocess.communicate() method seems to permanently close the stdin/stdout stream of the subprocess, which prevents me from sending it subsequent commands:

class _CLI:
def __init__(cls, appExe, appArgs, cmdlet, shell=True):
    cls._interface = subprocess.Popen(f"{appExe} {appArgs}", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell)

def _execute(cls, cmd)
    # ONLY WORKS ONCE
    cls._interface.stdin.write(f"{cmd}\n".encode(encoding))
    output, error = self._interface.communicate()
    return output, error
# ...

max = _CLI(appExe="powershell.exe", cmd="3dsMax", shell=True)
max._execute("SOMETHING COOL")

When I create a new subprocess for each command, that seems to work, but I specifically don't want to open a new application each time I run a command:

class _CLI:
def init(cls, appExe, appArgs, cmdlet, shell=True):
    cls._interface = None
    cls.appExe = appExe
    cls.appArgs = appArgs

def _execute(cls, cmd)
    # WORKS FOR SUBSEQUENT CALLS
    cls._interface = subprocess.Popen(f"{cls.appExe} {cls.appArgs}", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell) cls._interface.stdin.write(f"{cmd}\n".encode(encoding)) 
    output, error = self._interface.communicate()
    return output, error
#...

max = _CLI(appExe="powershell.exe", cmd="3dsMax", shell=True)
max._execute("SOMETHING COOL")

It seems that the status of stdin/stdout is a protected property, and subprocess doesn't have any accessible methods to re-open it. I noticed that subprocess.execute() has a timeout parameter, and I figured that maybe it was just waiting for an unspecified timeout (and hanging indefinitely since it wasn't set). However, adjusting that value didn't seem to do anything.

If anyone has any suggestions, I'd really appreciate it!

EDIT: fixed the busted formatting

Top answer
1 of 2
3
As an aside, you might find pexpect (or wexpect on Windows) more effective for this. https://pexpect.readthedocs.io/en/stable/
2 of 2
2
It's still a mystery to me why subprocess has a multitude of near identical functions that block until the process has finished completely. You cannot use communicate. You cannot use many of the other functions either. But you already use stdin.write which is your primary method of communication. If you want to give more commands you would just stdin.write again. In contrast to threading, Popen creates AND starts/runs a process. If you remove the communicate the process will still start up and receive and process your stdin just fine. (Maybe flushing could help if nothing is received.) If you want to send further instructions you can write them into stdin again. Whether the subprocess knows what to do with your stdin is another matter altogether. If your process has no GUI (just a console) and don't need the program to process stdout/stderr you could also remove the pipes on stdout and stderr which will print their messages directly into the console. If your program does need stdout/stderr you can .read though it takes some care to avoid blocking. Also, are you sure you need shell=True? This inserts a cmd.exe between Python and the command to start powershell.exe which should already be able to find things like 3dsMax. (And if you do start Python from a console anyway then the chain of commands is like cmd->python->cmd->powershell->3dsMax.) And the recommended first argument for Popen is a list. Use [cls.appExe, cls.appArgs].
🌐
Squash
squash.io › tutorial-subprocess-popen-in-python
Tutorial: Subprocess Popen in Python - Squash Labs
November 2, 2023 - To read from the subprocess's standard output or error stream, we can use the communicate method. This method waits for the subprocess to complete and returns a tuple containing the output and error streams.
🌐
Digitaldesignjournal
digitaldesignjournal.com › subprocess-communicate
How to use the subprocess Popen.communicate() method
September 22, 2023 - The subprocess.Popen.communicate() method is used to interact with a subprocess in Python. It allows you to send data to the subprocess’s standard input (stdin), read data from its standard output (stdout), and optionally capture data from ...
🌐
Masterccc
masterccc.github.io › memo › process_com
Python subprocess communication · Master 0xCcC
October 4, 2019 - Cheatsheet - Python subprocess communication Link to heading Imports Link to heading from subprocess import Popen, PIPE Imports for signals Link to heading import signal, os Start process Link to heading process = Popen(['./sum 50'], shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE) Check if process is alive Link to heading def isAlive(process): poll = process.poll() if poll == None: print("Program running...") else: print("Program stopped :(") Read from stdout Link to heading def getline(process): return "stdout : " + process.
🌐
Google Groups
groups.google.com › g › ansible-devel › c › yrQ_UaGOv0g
Usage of python's subprocess.Popen.communicate()
This new process outlives the rsync/ssh that spawned it, and holds onto stderr. Ansible is using Popen.communicate() from python's subprocess module, which not only blocks until the process finishes (that is, until wait() returns) but also blocks until stdout and stderr from the command are closed.
🌐
Reddit
reddit.com › r/learnpython › popen's communicate vs stdin.write: why warning? what instead?
r/learnpython on Reddit: Popen's communicate vs stdin.write: Why warning? What instead?
October 20, 2023 -

The Popen docs warn against using Popen.stdin (etc), saying:

Warning: Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

Is there further explanation somewhere? What does this warning mean practically, for the use of process.stdin.write and .flush in the example code below? Is there another way to send input to a running process, which doesn't assume the process will exit after receiving input?

For context, I've got several examples of executables that accept input on stdin continually, processing lines as they come in. I'd like to run one, send input to the process, and do other things in python before sending more input. The recommended Popen.communicate doesn't support this requirement, since it waits for the process to close after sending input. I haven't found any way to do it.

The following trimmed-down example code works with cat; the real example executables have more significant processing of their input.

import subprocess
import time

duration=1
items=[
    'spam',
    'spam & spam',
    'spam, spam, spam, eggs & spam'
    ]

with open( 'outfile', 'a' ) as outfile:
    with subprocess.Popen(
            [ 'cat' ],
            stdin=subprocess.PIPE,
            stdout=outfile,
            stderr=subprocess.DEVNULL
            ) as process:
        for item in items:
            process.stdin.write(\
                    ('order "' + item + '"\n')\
                    .encode( 'utf-8' ) )
            process.stdin.flush()
            time.sleep( duration )

(edit: this code actually works with the example executables, so I'm wondering when / if the deadlocks will actually affect me)