Asynchronous 从异步命令转到标准输出流

Asynchronous 从异步命令转到标准输出流,asynchronous,go,exec,Asynchronous,Go,Exec,我想使用GO在windows 10上运行异步命令。我正在运行的命令是阻塞的,如果直接从终端运行,它将提供持续的状态消息流,直到ctrl-c 我希望通过exec从GO运行该命令,并实时捕获exec命令到终端的输出,即不仅仅是在GO应用程序终止时 我尝试了许多示例,但没有成功,我只得到了一个空白的终端,即使在退出GO应用程序后,我也看不到我执行的命令的输出。您可以使用cmd.StdoutPipe来实现这一点: cmd := exec.Command(cmdName, cmdArgs...) cmdR

我想使用GO在windows 10上运行异步命令。我正在运行的命令是阻塞的,如果直接从终端运行,它将提供持续的状态消息流,直到ctrl-c

我希望通过exec从GO运行该命令,并实时捕获exec命令到终端的输出,即不仅仅是在GO应用程序终止时


我尝试了许多示例,但没有成功,我只得到了一个空白的终端,即使在退出GO应用程序后,我也看不到我执行的命令的输出。

您可以使用
cmd.StdoutPipe
来实现这一点:

cmd := exec.Command(cmdName, cmdArgs...)
cmdReader, _ := cmd.StdoutPipe()
scanner := bufio.NewScanner(cmdReader)
done := make(chan bool)
go func() {
    for scanner.Scan() {
        fmt.Printf(scanner.Text())
    }
    done <- true
}()
cmd.Start()
<- done
err = cmd.Wait()
cmd:=exec.Command(cmdName,cmdArgs…)
cmdReader,U3;:=cmd.StdoutPipe()
扫描程序:=bufio.NewScanner(cmdReader)
完成:=制作(陈波)
go func(){
对于scanner.Scan(){
fmt.Printf(scanner.Text())
}

谢谢,我已经尝试过了,但是运气不好,然后在进一步挖掘之后,我发现我正在运行的应用程序正在输出到Stderr,所以对我的环境做了一点小小的改变,这确实奏效了。我认为这种方法不是很可靠,至少在我在Travis CI上运行使用它的代码内部单元测试时是不可靠的。原因是什么原则上,命令的执行可以在goroutine到达读取输出的点之前完成,在
scanner.Scan()中
。发生这种情况时,输出管道将在扫描仪能够注册输出之前关闭,结果将丢失。一种可能的解决方法是在
cmd.Start()
之前等待一段时间,但这会减慢速度-我不知道任何可靠的方法来修复:(@Bronek请参见编辑,您可以使用一个通道进行阻止,直到您完成之前的所有输出continuing@dave-谢谢,这是一个健壮的解决方案。它利用了
scanner.Scan()
将保持循环运行直到子进程退出的事实。只有在这种情况下,我们才会继续执行
cmd.Wait()
关闭输出管道。如果我们想同时处理Stdout和Stderr,我们将使用两个单独的go例程,两个扫描器和计数为2的
sync.WaitGroup()
,而不是通道。