我试图从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)
我错过了什么让我无法阅读输出?
您可能需要检查多项内容。
cmd.StdoutPipe()不检查返回的错误代码。它应该是。
该pocketsphinx_continuous命令需要提供-hmm和参数。-dict否则,它将失败,并且所有输出实际上都发送到stderr而不是stdout。在这里,你只读了stdout,但没有什么可读的。
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)