我正在尝试从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)
}
在此示例中,"扫描程序已创建"打印出来,但之后没有任何事情发生。
然而,运行此命令确实会产生我期望打印到的内容:
/usr/local/bin/pocketsphinx_continuous -inmic yes 1>out.txt
修改代码以直接复制到stdout
也可以:
cmd := exec.Command("/usr/local/bin/pocketsphinx_continuous", "-inmic", "yes")
cmd.Stdout = os.Stdout
我错过了什么让我无法阅读输出?
答案 0 :(得分:4)
您可能需要检查多种内容。
未检查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
}
和主要代码:
stop := make(chan bool)
go readStuff(scanner,stop)
<-stop
cmd.Wait()
答案 1 :(得分:1)
似乎你不需要
go readStuff(scanner)
因为
cmd.Start()
做系统分叉本身 所以只是
readStuff(scanner)
对我来说已经足够了 (不是为此而产生的)
答案 2 :(得分:0)
这似乎工作正常,它适用于go readStuff(scanner)
,也适用于readStuff(scanner)
- 我不认为这种用法实际上需要goroutine,但不要知道实际情况。:
package main
import (
"bufio"
"fmt"
"os"
"os/exec"
)
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("/Users/rfay/bin/junk.sh")
out, err := cmd.StdoutPipe()
err = cmd.Start()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to start err=%v", err)
os.Exit(1)
}
scanner := bufio.NewScanner(out)
fmt.Println("Scanner created")
defer cmd.Wait()
go readStuff(scanner)
}
&#13;
这是我用来测试的垃圾。
#!/bin/bash
#!/bin/bash
for i in `seq 1 10`;
do
echo $i
sleep 1
done
&#13;