我正在尝试实时异步读取Stdout和Stderr。
这是有效的,但它在执行后永远挂起。我正在关闭管道,所以我不确定它在等待什么:
stdOutP, stdOutW := io.Pipe()
stdErrP, stdErrW := io.Pipe()
cmd := exec.Command("ping", "google.com", "-c", "10")
cmd.Stdout = io.MultiWriter(os.Stdout, stdOutW)
cmd.Stderr = io.MultiWriter(os.Stderr, stdErrW)
stdOutScanner := bufio.NewScanner(stdOutP)
stdErrScanner := bufio.NewScanner(stdErrP)
stdOutDone := make(chan bool)
go func() {
defer stdOutP.Close()
for stdOutScanner.Scan() {
// Do something with output...
fmt.Println("From stdOut buffer: " + stdOutScanner.Text())
}
stdOutDone <- true
}()
stdErrDone := make(chan bool)
go func() {
defer stdErrP.Close()
for stdErrScanner.Scan() {
// Do something with output...
fmt.Println("From stdErr buffer: " + stdErrScanner.Text())
}
stdErrDone <- true
}()
err := cmd.Start()
<-stdOutDone
<-stdErrDone
err = cmd.Wait()
if err != nil {
fmt.Printf(err.Error())
}
字符串
我甚至尝试在cmd.Wait()
调用之前和之后关闭通道
close(stdOutDone)
close(stdErrDone)
型
编辑
我得到了我的答案。
封闭式的writer not reader:
defer stdOutW.Close()
defer stdErrW.Close()
型
然后在运行Start()之前关闭通道-这让我很困惑。通道什么时候关闭?我希望什么都不会发生,因为我在启动命令之前关闭它们!
close(stdOutDone)
close(stdErrDone)
err := cmd.Start()
型
1条答案
按热度按时间v09wglhw1#
要中断扫描循环并退出goroutines,请在命令退出后关闭管道的写入端。额外的好处:使用sync.WaitGroup等待goroutines完成。
字符串
https://go.dev/play/p/uUib9AiDCft