从子进程读取Stdout

tgr*_*ger 9 go

我试图从Golang生成一个子进程.目标是逐行读取和处理输入.这是我想要的工作:

func readStuff(scanner *bufio.Scanner) {
    for scanner.Scan() {
        fmt.Println("Performed Scan")
        fmt.Println(scanner.Text())
    }
    if err := scanner.Err(); err != nil {
        fmt.Fprintln(os.Stderr, "reading standard input:", err)
    }
}

func main() {
    cmd := exec.Command("/usr/local/bin/pocketsphinx_continuous", "-inmic", "yes")
    out, err := cmd.StdoutPipe()

    err = cmd.Start()
    checkError(err)

    scanner := bufio.NewScanner(out)
    fmt.Println("Scanner created")

    defer cmd.Wait()
    go readStuff(scanner)
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,打印了"扫描仪创建",但之后没有任何反应.

但是,运行此命令会导致我希望打印到的内容:

/usr/local/bin/pocketsphinx_continuous -inmic yes 1>out.txt
Run Code Online (Sandbox Code Playgroud)

并修改代码直接复制到stdout工作:

cmd := exec.Command("/usr/local/bin/pocketsphinx_continuous", "-inmic", "yes")
cmd.Stdout = os.Stdout
Run Code Online (Sandbox Code Playgroud)

我错过了什么让我无法阅读输出?

Did*_*zia 6

您可能需要检查多项内容。

  1. cmd.StdoutPipe()不检查返回的错误代码。它应该是。

  2. pocketsphinx_continuous命令需要提供-hmm和参数。-dict否则,它将失败,并且所有输出实际上都发送到stderr而不是stdout。在这里,你只读了stdout,但没有什么可读的。

  3. cmd.Wait()在确定所有数据均已从 中读取之前,不应调用stdout。结果是不确定的(实际上,这是一个竞争条件)。检查有关该包的文档os/exec。如果你绝对需要在 Goroutine 中完成解析,则需要在cmd.Wait()调用之前与 Goroutine 的末尾同步。例如,您可以将该函数编写为:

    func readStuff(scanner *bufio.Scanner, stop chan bool) {
        // Scanning code
        // ...
        stop<-true
    }
    
    Run Code Online (Sandbox Code Playgroud)

    主要代码为:

    stop := make(chan bool)
    go readStuff(scanner,stop)
    <-stop
    cmd.Wait()
    
    Run Code Online (Sandbox Code Playgroud)