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.