我使用以下有效的代码,问题是输出与进程完成执行时一样被打印,我想将输出实时打印到屏幕上,而在进程完成时不提供所有输出,我该如何实现?
cmdParams := [][]string{ {filepath.Join(dir,path), "npm", "install"}, {filepath.Join(pdir,n.path), "gulp"}, } for _, cp := range cmdParams { log.Printf("Starting %s in folder %s...", cp[1:], cp[0]) cmd := exec.Command(cp[1], cp[2:]...) cmd.Dir = cp[0] // Wait to finish, get output: out, err := cmd.Output() if err != nil { log.Printf("Error running %s: %v\n", cp[1:], err) return } log.Println("Finished %s, output: %s", cp[1:], out) }
*尝试提出的解决方案时 *更新 ,我得到的输出像
2018/02/18 11:11:57 Starting [npm install] in folder ... 2018/02/18 11:12:14 adde 2018/02/18 11:12:14 d 56 2018/02/18 11:12:14 3 pa 2018/02/18 11:12:14 ckag 2018/02/18 11:12:14 es i 2018/02/18 11:12:14 n 15 2018/02/18 11:12:14 .477 2018/02/18 11:12:14 s 2018/02/18 11:12:14 Finished %s [npm install]
使用此答案中提供的解决方案:流命令输出进度
cmdParams := [][]string{ {filepath.Join(dir, path), "npm", "install"}, {filepath.Join(pdir, n.path), "gulp"}, } for _, cp := range cmdParams { log.Printf("Starting %s in folder %s...", cp[1:], cp[0]) cmd := exec.Command(cp[1], cp[2:]...) cmd.Dir = cp[0] stdout, err := cmd.StdoutPipe() if err != nil { log.Printf("%s cmd.StdoutPipe() error: %v\n", cp[1:], err) return } // Start command: if err = cmd.Start(); err != nil { log.Printf("%s start error: %v\n", cp[1:], err) return } // Stream command output: scanner := bufio.NewScanner(stdout) scanner.Split(bufio.ScanRunes) for scanner.Scan() { fmt.Print(scanner.Text()) } if scanner.Err() != nil { log.Printf("Reading %s stdout error: %v\n", cp[1:], err) return } // Get execution success or failure: if err = cmd.Wait(); err != nil { log.Printf("Error running %s: %v\n", cp[1:], err) return } log.Printf("Finished %s", cp[1:]) }
一些解释:
这行:
scanner := bufio.NewScanner(stdout)
创建一个bufio.Scanner将从提供该进程写入的输出的管道读取的。
bufio.Scanner
scanner.Split(bufio.ScanRunes)
指示扫描程序以runes代替默认行来读取输入。
rune
请注意,上面的示例仅流式处理标准输出。如果您还需要标准错误流,也可以从阅读Command.StderrPipe()。
Command.StderrPipe()
还要注意,这不适用于某些命令不能将所有内容写入其标准输出或错误的命令。