doutang7414 2013-10-29 20:25 采纳率: 0%
浏览 41
已采纳

Go中的持久性程序

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?

  • 写回答

2条回答 默认 最新

  • duankekan9269 2013-10-29 21:30
    关注

    Your biggest issue is you're reassigning the command's Stdin, instead of piping to it.

    Here's a working version:

    package main
    
    import (
        "bufio"
        "fmt"
        "math/rand"
        "os/exec"
        "time"
    )
    
    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)
        }
    
        progout, err := cmd.StdinPipe()
        if err != nil {
            fmt.Println("Trouble with e's stdin")
            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)
            progout.Write([]byte(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)
    
        }
    }
    

    And e.go with a few fixups:

    package main
    
    import (
        "bufio"
        "fmt"
        "os"
        "strings"
    )
    
    func main() {
        for {
            buf := bufio.NewReader(os.Stdin)
            input, err := buf.ReadString('
    ')
    
            if err != nil {
                fmt.Println("Echo failed: ", input)
                panic(err)
            }
    
            if strings.HasPrefix(input, "exit") {
                fmt.Println("Bye!")
                return
            }
    
            fmt.Print(input)
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效