You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 03:44:55