golang執行命令實時輸出(協程通過channel更新資料到主程序)
阿新 • • 發佈:2020-11-02
func TestCmdOut(t *testing.T) { fmt.Println("start") cmdstr := "dir /s C:" cmd := exec.Command("cmd","/c",cmdstr) fmt.Println("11111111") stdout,err := cmd.StdoutPipe() if err != nil { fmt.Println(err) return } stderr,err := cmd.StderrPipe() if err != nil { fmt.Println(err) return } err = cmd.Start() if err != nil { fmt.Println(err) } stdoutScanner := bufio.NewScanner(stdout) stderrScanner := bufio.NewScanner(stderr) charset := GB18030 totalOut := "" totalErr := "" outChan := make(chan string, 10000) errChan := make(chan string, 10000) exeEnd := false go func(scanner *bufio.Scanner) { for scanner.Scan() { stdoutstr := ConvertByte2String(scanner.Bytes(), charset) outChan <- stdoutstr } exeEnd = true }(stdoutScanner) go func(scanner *bufio.Scanner) { for scanner.Scan() { stderrstr := ConvertByte2String(scanner.Bytes(), charset) errChan <- stderrstr } }(stderrScanner) j := 0 for { for i:=0;i<10000;i++ { select { case outTemp := <- outChan: fmt.Println("chan:"+outTemp) totalOut += "\n" + outTemp default: fmt.Println(fmt.Sprintf("j:%d",j)) fmt.Println("direct end") goto outexit } } outexit: for i:=0;i<10000;i++ { select { case errTemp := <- errChan: totalErr += "\n" + errTemp default: fmt.Println("err direct end") goto errexit } } errexit: fmt.Println(fmt.Sprintf("totalOut:%s",totalOut)) fmt.Println(fmt.Sprintf("totalErr:%s",totalErr)) time.Sleep(1*time.Second) fmt.Println(exeEnd) if exeEnd { j += 1 } if j>=2 { break } } err = cmd.Wait() }