10

This is certainly answered as part of a long discussion about subprocess elsewhere. But the answer is so simple it should be broken out.

How do I pass a string "foo" to a program expecting it on stdin if I use Python 3's subprocess.run()?

Ray Salemi
  • 4,017
  • 2
  • 24
  • 50

2 Answers2

6

Simplest possible example, send foo to cat and let it print to the screen.

 import subprocess

 subprocess.run(['cat'],input=b'foo\n')

Notice that you send binary data and the carriage return.

Ray Salemi
  • 4,017
  • 2
  • 24
  • 50
4

Pass text=True and input="whatever string you want" to subprocess.run:

import subprocess
subprocess.run("cat", text=True, input="foo\n")

Per the docs for subprocess.run:

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. When used, the internal Popen object is automatically created with stdin=PIPE, and the stdin argument may not be used as well.


universal_newlines was renamed to text in Python 3.7, so on older versions you have to use universal_newlines=True instead of text=True:

subprocess.run("cat", universal_newlines=True, input="foo\n")

and you might want to add capture_output=True if you want the output of the command as a string:

subprocess.run("cat", universal_newlines=True, capture_output=True, input="foo\n")
Boris Verkhovskiy
  • 10,733
  • 7
  • 77
  • 79
  • capture_output is also a Python 3.7 addition so if you're using universal_newlines you'll also want to direct stderr and stdout - https://stackoverflow.com/questions/53209127/subprocess-unexpected-keyword-argument-capture-output/53209196 – riskyc123 Jan 21 '21 at 11:33