I'm trying to learn Go, and I thought I'd start with a project I've wanted to do for some time (but which seemed too 'fiddly' to bother with). The essential idea is that I have a program which interacts with the user on stdin/stdout and I'd like to write a new program which interacts with the program in the same way (as if it were a person running the program).
Now the program here is simple, in that it's synchronous: you enter a command, get some output, and then it sits there waiting for the next batch of input. That didn't seem so hard, but I'm having trouble getting this I/O skeleton working.
package main
import (
"os/exec"
"time"
"bufio"
"math/rand"
"fmt"
"strings"
)
func main() {
cmd := exec.Command("e") // A simple program that echos input until it becomes "exit"
progin, err := cmd.StdoutPipe()
if err != nil {
fmt.Println("Trouble with e's stdout")
panic(err)
}
err = cmd.Start()
if err != nil {
fmt.Println("Trouble starting e")
panic(err)
}
r := rand.New(rand.NewSource(99))
buf := bufio.NewReader(progin)
for {
// Write stuff
var toProg string
if (r.Float64() < .1) {
toProg = "exit"
} else {
toProg = fmt.Sprintf("%d", r.Int)
}
fmt.Println("Printing: ", toProg)
cmd.Stdin = strings.NewReader(toProg + "
")
// Read stuff
time.Sleep(500 * time.Millisecond) // give the program time to generate output
input, err := buf.ReadString('
')
if err != nil {
fmt.Println("I did *not* like that: ", input)
panic(err)
}
fmt.Println("Received: ", input)
}
}
Any takers?