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
相关产品推荐
相关产品推荐

