Reputation: 429
GO: Is there some way to communicate with a subprocess (shell script / python script), which is waiting for input on stdin?
e.g. python script (subprocess)
import sys
while True:
sys.stdout.write('%s\n'%eval(sys.stdin.readline()))
In the go program, I want to create a subprocess of this python script and provide it input on its stdin, whenever necessary and repeatedly, and take its output. Writing on stdout of Go program or reading/writing from a file will also do.
This is roughly what I am trying, but nothing happens -
c := exec.Command("python", "-u add.py")
si,_ := c.StdinPipe()
so,_ := c.StdoutPipe()
c.Start()
si.Write([]byte("2+2\n")
Upvotes: 7
Views: 2217
Reputation: 54079
Here is a working version of your go code (python code is unchanged).
Note: checking of all errors, fixed -u
flag, use of bufio to read a line, and Wait to wait for end of process.
import (
"bufio"
"fmt"
"log"
"os/exec"
)
func main() {
c := exec.Command("python", "-u", "add.py")
si, err := c.StdinPipe()
if err != nil {
log.Fatal(err)
}
so, err := c.StdoutPipe()
if err != nil {
log.Fatal(err)
}
reader := bufio.NewReader(so)
err = c.Start()
if err != nil {
log.Fatal(err)
}
// Now do some maths
for i := 0; i < 10; i++ {
sum := fmt.Sprintf("2+%d\n", i)
_, err = si.Write([]byte(sum))
if err != nil {
log.Fatal(err)
}
answer, err := reader.ReadString('\n')
if err != nil {
log.Fatal(err)
}
fmt.Printf("Answer to %q is %q\n", sum, answer)
}
// Close the input and wait for exit
si.Close()
so.Close()
c.Wait()
}
Which produces
Answer to "2+0\n" is "2\n"
Answer to "2+1\n" is "3\n"
Answer to "2+2\n" is "4\n"
Answer to "2+3\n" is "5\n"
Answer to "2+4\n" is "6\n"
Answer to "2+5\n" is "7\n"
Answer to "2+6\n" is "8\n"
Answer to "2+7\n" is "9\n"
Answer to "2+8\n" is "10\n"
Answer to "2+9\n" is "11\n"
Upvotes: 5