I want to invoke a script, piping the contents of a string to its stdin and retrieving its stdout.
I don't want to touch the real filesystem so I can't create real temporary files for it.
using subprocess.check_output
I can get whatever the script writes; how can I get the input string into its stdin though?
subprocess.check_output([script_name,"-"],stdin="this is some input") Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib/python2.7/subprocess.py", line 537, in check_output process = Popen(stdout=PIPE, *popenargs, **kwargs) File "/usr/lib/python2.7/subprocess.py", line 672, in __init__ errread, errwrite) = self._get_handles(stdin, stdout, stderr) File "/usr/lib/python2.7/subprocess.py", line 1043, in _get_handles p2cread = stdin.fileno() AttributeError: 'str' object has no attribute 'fileno'
The subprocess. check_output() is used to get the output of the calling program in python. It has 5 arguments; args, stdin, stderr, shell, universal_newlines. The args argument holds the commands that are to be passed as a string.
To pass variables to Python subprocess. Popen, we cann Popen with a list that has the variables we want to include. to call Popen with the command list that has some static and dynamic command arguments.
To write to a Python subprocess' stdin, we can use the communicate method. to call Popen with the command we want to run in a list. And we set stdout , stdin , and stderr all to PIPE to pipe them to their default locations.
Use Popen.communicate
instead of subprocess.check_output
.
from subprocess import Popen, PIPE p = Popen([script_name, "-"], stdin=PIPE, stdout=PIPE, stderr=PIPE) stdout, stderr = p.communicate("this is some input")
In Python 3.4 and newer, you can use the input keyword parameter to send input via STDIN when using subprocess.check_output()
Quoting from the standard library documentation for subprocess.check_output()
:
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 ifuniversal_newlines=True
. When used, the internalPopen
object is automatically created withstdin=PIPE
, and the stdin argument may not be used as well.
Example:
>>> subprocess.check_output(["sed", "-e", "s/foo/bar/"], ... input=b"when in the course of fooman events\n") b'when in the course of barman events\n' >>> >>> # To send and receive strings instead of bytes, >>> # pass in universal_newlines=True >>> subprocess.check_output(["sed", "-e", "s/foo/bar/"], ... universal_newlines=True, ... input="when in the course of fooman events\n") 'when in the course of barman events\n'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With