How do I pass a string into subprocess.Popen using the stdin argument?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
To send a string to a child process in Python, create the process with stdin=subprocess.PIPE and then pass the text to communicate(). That pattern is the safest answer because it writes the input, closes standard input, waits for completion, and collects output without leaving the process hanging.
The Standard Popen Pattern
For ordinary text input, enable text mode so Python handles encoding and decoding for you.
Here is what matters:
- '
stdin=subprocess.PIPEgives Python a writable pipe connected to the child's standard input' - '
text=Truemeanscommunicateaccepts and returns strings instead of bytes' - '
stdout=subprocess.PIPEandstderr=subprocess.PIPElet you inspect the result'
If you only remember one technique, remember this one.
Why communicate() Is Preferred
You can manually write to proc.stdin, but communicate() is usually better because it handles the full request-response lifecycle in one call. It:
- writes the input data
- closes stdin so the child sees end-of-input
- waits for the command to exit
- reads stdout and stderr safely
That last point matters. Pipes have finite buffers. If you manually write to stdin while the child also produces lots of output, you can deadlock unless you manage both sides carefully.
Sending Bytes Instead Of Text
If the child process expects binary input, do not use text=True. Send bytes directly.
In this version, stdout and stderr are also bytes. That is useful when the data is not plain text or when you need exact byte preservation.
A More Realistic Example
Suppose you want to send SQL text or some generated configuration into another command. The mechanism is identical.
The example child process just uppercases what it reads, but the important part is that your string goes through standard input, not through shell quoting.
Manual Writes Are Possible, But Riskier
You can write to proc.stdin directly if you need a conversational process, but then you must manage the lifecycle yourself.
This works for simple cases, but it is easier to misuse than communicate(). If the child expects more input, or if stderr fills up and is never read, the process can stall.
Timeouts And Error Handling
When the subprocess might hang, add a timeout.
This is the correct cleanup pattern: kill the process, then call communicate() again to drain any remaining output.
subprocess.run Is Simpler For One-Shot Calls
If you do not need the Popen object itself, subprocess.run is shorter and built around the same idea.
Use Popen when you need lower-level control. Use run when you just want to send input once and get the result.
Common Pitfalls
A common mistake is forgetting stdin=subprocess.PIPE. Without that, there is no writable pipe for Python to send the string to.
Another issue is mixing text and bytes incorrectly. If text=True is off, communicate() expects bytes, not Python strings. If text=True is on, send strings and let Python handle encoding.
Developers also sometimes write to proc.stdin manually but never close it. Many programs wait for end-of-input before continuing, so the child appears to hang even though it is behaving correctly.
Finally, do not use shell=True just to pass input data. Standard input is cleaner and avoids shell-quoting bugs.
Summary
- Use
stdin=subprocess.PIPEandcommunicate()to pass a string into a subprocess safely. - Turn on
text=Truewhen you want to work with Python strings instead of bytes. - Use raw bytes only when the child process expects binary input.
- Prefer
communicate()over manual writes for one-shot interactions. - Add timeouts and proper cleanup when the subprocess might block or run too long.
Related reading
- How do I pass an async function to a thread target in Python?
- How do I plot in real-time in a while loop?
- How do I prepend to a short python list?
- How do I prevent Conda from activating the base environment by default?
- How do I print an exception in Python?
- How do I print an exception in Python?
- How do I print the full NumPy array, without truncation?
- How do I print the full NumPy array, without truncation?
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.