Go中exec.Wait()永久挂起问题排查及解决疑问
实时异步读取命令输出时程序永久挂起的问题与解决
我尝试实时异步读取命令的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)
编辑
根据提示我找到了解决方案——关闭写入端而非读取端:
defer stdOutW.Close() defer stdErrW.Close()
但我对此感到困惑:在启动命令前关闭通道?我以为这样不会有任何效果!
close(stdOutDone) close(stdErrDone) err := cmd.Start()
内容的提问来源于stack exchange,提问作者red888
相关产品推荐
相关产品推荐

