doujunchi1238 2014-12-20 04:24
浏览 55

从子流程读取Stdout

I am attempting to spawn a subprocess from Golang. The goal is to read and process the input line-by-line. Here is what I am trying to get working:

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)
}

In this example, "Scanner created" is printed, but nothing happens after that.

Running this command however does result in what I am expecting to be printed to :

/usr/local/bin/pocketsphinx_continuous -inmic yes 1>out.txt

And modifying the code to directly copy to stdout works as well:

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

What am I missing that is keeping me from reading the output?

  • 写回答

3条回答 默认 最新

  • dsms21398 2014-12-20 11:12
    关注

    There are multiple things you may want to check.

    1. The error code returned by cmd.StdoutPipe() is not checked. It should be.

    2. The pocketsphinx_continuous command requires the -hmm and -dict arguments to be provided. Otherwise, it will fail, and all the output is actually sent to stderr and not stdout. Here, you read only stdout, but there is nothing to read.

    3. You should not call cmd.Wait() before being sure all the data have been read from stdout. The result is non deterministic (actually, it is a race condition). Check the documentation about the os/exec package. If you absolutely need the parsing to be done in a goroutine, you need to synchronize with the end of the goroutine before cmd.Wait() is called. For instance, you could write the function as:

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

      and the main code as:

      stop := make(chan bool)
      go readStuff(scanner,stop)
      <-stop
      cmd.Wait()
      
    评论

报告相同问题?

悬赏问题

  • ¥15 谁有RH342练习环境
  • ¥15 STM32F407 DMA中断问题
  • ¥15 uniapp连接阿里云无法发布消息和订阅
  • ¥25 麦当劳点餐系统代码纠错
  • ¥15 轮班监督委员会问题。
  • ¥15 基于作物生长模型下,有限水资源的最大化粮食产量的资源优化模型建立
  • ¥20 关于变压器的具体案例分析
  • ¥15 生成的QRCode圖片加上下載按鈕
  • ¥15 板材切割优化算法,数学建模,python,lingo
  • ¥15 科来模拟ARP欺骗困惑求解