The restriction to Python2.6 was added to the question later on. A portable solution is at the end of this answer.
Since Python 3.5, subprocess.run
should match most "call program with X" use cases. It's input
parameter does what you want:
The input
argument is passed to [...] the subprocess’s stdin.
You can feed it a bytes string directly:
import subprocess
g2p_process = subprocess.run(["./eng_GBR/g2p", "@g2pumap=./map.txt"], input=b'teststring\n')
This is equivalent to your bash call. Note that you must add appropriate newlines (b"\n"
at the end) by yourself. Any arguments, such as @g2pumap=./map.txt
, can be passed in without escaping.
If you want to have the Exception of check_call
, use g2p_process.check_returncode()
afterwards.
If you are stuck with an older version or need backwards compatibility, using a bare subprocess.Popen
is the most portable. The following should handle your use case:
import subprocess
g2p_process = subprocess.Popen(
["./eng_GBR/g2p", "@g2pumap=./map.txt"],
stdin=subprocess.PIPE, # allow sending data via STDIN
)
g2p_process.communicate(input="teststring\n")
if g2p_process.returncode != 0:
raise RuntimeError
Note that you can also capture stdout and stderr if you need to. Use stdout=subprocess.PIPE
and/or stderr=subprocess.PIPE
in the call to Popen
. Doing so lets g2p_process.communicate
return a meaningful tuple of (stdoutdata, stderrdata)
.
See the subprocess.Popen
method docs on how to work with such an object. It is usually a good idea to check its returncode
, or kill
dangling processes. You can also replicate subprocess.run
if you feel like it, since it does proper error handling.