Pass stdin to a Command in Python with subprocess.run
Send text to a command's standard input with subprocess.run(input=...). A str needs text=True, bytes need none, and input cannot be combined with stdin.
You want to feed data to a program such as sort without writing a temporary file.
import subprocess
r = subprocess.run(["sort"], input="pear\napple\nfig\n", capture_output=True, text=True)
print(r.stdout, end="")
r = subprocess.run(["wc", "-c"], input=b"\x00\x01\x02", capture_output=True)
print(r.stdout.decode().strip())
try:
subprocess.run(["sort"], input=b"bytes", text=True)
except TypeError as e:
print("TypeError:", e)
try:
subprocess.run(["sort"], input="x", stdin=subprocess.DEVNULL)
except ValueError as e:
print("ValueError:", e)apple
fig
pear
3
TypeError: write() argument must be str, not bytes
ValueError: stdin and input arguments may not both be used.The input argument is written to the child's standard input and then closed. With text=True it must be a str, as in the first call that sorted three words. Without it, input must be bytes, and wc -c counted three bytes. Mixing them up produces TypeError: write() argument must be str, not bytes, and passing both input and stdin raises ValueError. See subprocess.run.
input is sent in one piece and the call blocks until the child exits, so it suits modest amounts of data. To stream a large input while reading output, use Popen and communicate, or threads. A child that does not read its input, such as true, may fail with a broken pipe.