一。提出問題,cmd.StderrPipe()和cmd.StdoutPipe()都無法獲取后續(xù)輸出
有時(shí)候在執(zhí)行 exec.Command 的命令的時(shí)候,需要實(shí)時(shí)獲取命令的輸出,并不是一次性輸出的,一般情況下都會(huì)用 cmd.StderrPipe() 以及 cmd.StdoutPipe() 來獲取,比如你執(zhí)行 ping 命令,但是,有些命令,只能接受第一次的輸出,后續(xù)的無法接受到,拿這里的 tshark 命令為例
二,問題原因解釋,可能是命令本身原因
這可能是由于 tshark 命令在進(jìn)行數(shù)據(jù)捕獲時(shí)會(huì)一直輸出,直到用戶中斷命令或者捕獲到結(jié)束符為止。因此,cmd.StderrPipe()和cmd.StdoutPipe()只能獲取tshark命令的初始輸出,而無法獲取后續(xù)輸出。
要解決此問題,您可以通過在執(zhí)行tshark命令時(shí)加入“-l”選項(xiàng)來強(qiáng)制tshark在輸出每一行數(shù)據(jù)后刷新緩沖區(qū),這樣您就可以實(shí)時(shí)獲取到輸出。例如:
exec.Command("bash", "-c", "tshark -l -i 你的網(wǎng)卡名稱 -n -T fields -e eth.src -e ip.src port 68")
三。代碼例子(只不過在命令中 加了一個(gè) -l 而已)
func useScan() {
go func() {
for {
cmd := exec.Command("bash", "-c", "tshark -l -i 你的網(wǎng)卡名稱 -n -T fields -e eth.src -e ip.src port 68")
cmd.Run()
time.Sleep(time.Second * 2)
}
}()
cmd := exec.Command("bash", "-c", "tshark -l -i 你的網(wǎng)卡名稱 -n -T fields -e eth.src -e ip.src port 68")
stderr, err := cmd.StderrPipe()
if err != nil {
return
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return
}
if err := cmd.Start(); err != nil {
return
}
go func() {
scanner := bufio.NewScanner(stderr)
for scanner.Scan() {
line := scanner.Text()
log.Println("stderr:", line)
}
}()
go func() {
scanner := bufio.NewScanner(stdout)
for scanner.Scan() {
line := scanner.Text()
log.Println("stdout:", line)
}
}()
cmd.Wait()
}
這樣,您就可以實(shí)時(shí)獲取tshark命令的輸出了。
四。結(jié)論及回顧
在執(zhí)行命令中,要注意該命令是否只寫入緩沖(該命令自己的緩沖),因?yàn)樗惠敵龅轿覀兂绦虻墓艿乐?,我們就無法獲取到他的輸出,其他命令同理,其他無法獲取內(nèi)容的,注意一下就行,看看哪個(gè)參數(shù)可以強(qiáng)制在輸出每一行數(shù)據(jù)后刷新緩沖區(qū),這樣您就可以實(shí)時(shí)獲取到輸出