By default, subprocess.run()
takes stdin
(standard input) from our Python program and passes it through unchanged to the subprocess.
For example, on a Linux or macOS system, the cat -
command outputs exactly what it receives from stdin
. If we run the following code on a Linux or macOS system:
1 2 3 | from subprocess import run run( [ 'cat', '-' ] ) |
cat
will wait for input from the user. When the user enters input to our Python program's stdin
, Python sends that input data to the cat
subprocess, which then displays the input on-screen.
If we want to programmatically specify the standard input data for the command we're running, we can use the input=
option when calling subprocess.run()
. By default, input=
accepts bytes
, so we can pass binary data bytes
directly using the parameter.
The following example loads the binary data contents of myfiles.tar.gz
and sends it to the tar
command as stdin
:
1 2 3 4 5 6 | from subprocess import run with open( 'myfiles.tar.gz', 'rb' ) as f: data = f.read() run( [ 'tar', 'xzf', '-' ], input=data ) |
If a user runs this Python program, the tar xzf -
command will extract the contents of myfiles.tar.gz
in the user's current directory to the user's current directory.
Since standard input is provided by input=data
, the Python program will not wait for the user to input anything.
.encode()
Since input=
expects bytes
, if we want to pass in a string, we can first convert the string to bytes
using UTF-8 encoding with .encode()
:
1 2 3 4 | from subprocess import run message = 'Hello, world!\n' run( [ 'cat', '-' ], input=message.encode() ) |
encoding=
optionAlternatively, we could have used the encoding
, errors
or text
parameters along with input
and passed in message
directly as a string
.