通过Go程序调用外部可执行文件出现无响应问题的排查请求
通过Go程序调用外部可执行文件出现无响应问题的排查请求
我遇到了一个奇怪的问题:在Windows命令提示符里直接运行外部可执行文件并携带参数完全正常,命令如下:
cgx_STATIC.exe -b C:\Users\m3\AppData\Local\Temp\shot-277325955.fbd
但当我用Go代码调用同一个可执行文件时,程序在生成部分输出文件后就卡住无响应了。
我的初始Go实现代码如下,功能是调用可执行文件并将其日志输出到指定文件:
// Run an executable and print its log into a file. func RunWithLogFile(pthExe string, arg []string, fLog *os.File) error { cmd := exec.Command(pthExe, arg...) stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } err = cmd.Start() if err != nil { return err } // Stream logs scannerOut := bufio.NewScanner(stdout) scannerErr := bufio.NewScanner(stderr) scannerOut.Split(bufio.ScanRunes) scannerErr.Split(bufio.ScanRunes) for scannerOut.Scan() { _, err = fLog.WriteString(scannerOut.Text()) if err != nil { return err } } for scannerErr.Scan() { _, err = fLog.WriteString(scannerErr.Text()) if err != nil { return err } } if scannerOut.Err() != nil { return err } if scannerErr.Err() != nil { return err } err = cmd.Wait() return err }
我想知道这段Go代码是不是存在什么bug,或者本身就不适合用来调用这类可执行文件?
后来我尝试了用独立goroutine分别读取stdout和stderr的方案(参考了他人建议),但问题依然没有解决,改进后的代码如下:
// Run an executable and print its log into a file. func RunWithLogFile(pthExe string, arg []string, fLog *os.File) error { cmd := exec.Command(pthExe, arg...) stdout, err := cmd.StdoutPipe() if err != nil { return err } stderr, err := cmd.StderrPipe() if err != nil { return err } var wg sync.WaitGroup wg.Add(2) go streamToLogFile(stdout, fLog, &wg) go streamToLogFile(stderr, fLog, &wg) err = cmd.Start() if err != nil { return err } wg.Wait() err = cmd.Wait() return err } func streamToLogFile(output io.ReadCloser, fLog *os.File, wg *sync.WaitGroup) { defer wg.Done() scanner := bufio.NewScanner(output) scanner.Split(bufio.ScanRunes) for scanner.Scan() { _, err := fLog.WriteString(scanner.Text()) if err != nil { log.Printf("error: write to log file: %s", err.Error()) } } err := scanner.Err() if err != nil { log.Printf("error: write to log file: %s", err.Error()) } }
备注:内容来源于stack exchange,提问作者Megidd
相关产品推荐
相关产品推荐

