0

I have a bash script file called g2p which runs as following:

$echo "teststring" | ./g2p @g2pumap=./map.txt

Now I am writing a python script using python 2.6, I need to run this bash script( g2p) inside python.

I checked this answer:Python: subprocess and running a bash script with multiple arguments

I wrote:

import subprocess

val = subprocess.check_call(["./eng_GBR/g2p",  "./map.txt"],  shell=True) 

my problem is how to send standard input to g2p (bash script) inside python code, and also I get a bit confused about pass value to @g2pumap argument.

Mahsa
  • 207
  • 1
  • 10

2 Answers2

2

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.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
0
import subprocess

value1=...
value2=...
......

val = subprocess.check_call(["path/script.sh",  value1+" "+value2+" "+ .... ],  shell=True) 
helloworld
  • 59
  • 1
  • 9