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

Go代码运行出现‘exec: not started’错误,是否该忽略?

问题分析与解决方案

错误根源

你碰到的exec: not started错误,核心原因是执行cmd.Wait()的goroutine在cmd.Start()完成前就触发了。代码里你先把三个goroutine都加入了errgroup,然后才调用cmd.Start()——goroutine是并发执行的,那个负责Wait的goroutine很可能抢在命令启动前就调用了cmd.Wait(),而Go的exec包明确规定:未启动的命令调用Wait会返回这个错误。

隐患说明

别觉得现在功能正常就可以忽略,这个问题存在明确隐患:

  • 要是cmd.Start()执行失败(比如命令不存在、权限不够),Wait的goroutine已经在跑了,会提前抛出错误,打乱原本的错误处理逻辑
  • 高并发或者系统负载高的场景下,这个错误出现的概率会大幅提升,可能导致程序异常退出或者日志混乱
  • 违反了exec包的使用规范,后续Go版本如果调整exec包的行为,可能引发更严重的兼容性问题

修复代码

把启动Wait goroutine的代码移到cmd.Start()成功之后,确保命令已经启动再调用Wait:

// Go routines for non-blocking reading of stdout and stderr and writing to files
g := new(errgroup.Group)

// Read stdout in goroutine.
g.Go(func() error {
    err = writeFromProcessToFileWithMax(stdoutScanner, stdoutFileWriter, maxStdoutFileLengthInGB)
    if err != nil {
        log.Error().Err(err).Msgf("Error writing to stdout file: %s", stdoutFilename)
        return err
    }
    return nil
})

// Read stderr in goroutine.
g.Go(func() error {
    err = writeFromProcessToFileWithMax(stderrScanner, stderrFileWriter, maxStderrFileLengthInGB)
    if err != nil {
        log.Error().Err(err).Msgf("Error writing to stderr file: %s", stderrFilename)
        return err
    }
    return nil
})

// Starting the command
if err = cmd.Start(); err != nil {
    log.Error().Err(err).Msg("Error starting command")
    return err
}

// Wait the command in a goroutine - 移到Start成功后,确保命令已启动
g.Go(func() error {
    return cmd.Wait()
})

// Waiting until errorGroups groups are done
if err = g.Wait(); err != nil {
    log.Error().Err(err).Msg("Error during running of the command")
}

内容的提问来源于stack exchange,提问作者aronchick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:40:54