golang执行命令实时输出(协程通过channel更新数据到主进程)
type Charset string
const (
UTF8 = Charset("UTF-8")
GB18030 = Charset("GB18030")
)
//对字符进行转码
func ConvertByte2String(byte []byte, charset Charset) string {
var str string
switch charset {
case GB18030:
var decodeBytes,_=simplifiedchinese.GB18030.NewDecoder().Bytes(byte)
str= string(decodeBytes)
case UTF8:
fallthrough
default:
str = string(byte)
}
return str
}
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() }