亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 os/exec.Cmd.Wait() 之后保留標準輸出

在 os/exec.Cmd.Wait() 之后保留標準輸出

Go
HUWWW 2022-12-13 16:23:53
我正在使用 os/exec,在命令運行時發送輸入和接收輸出。我需要在命令完成時存儲命令的返回碼,所以我有一個帶有 的 goroutine err := cmd.Wait(),并且我從錯誤中獲取任何失敗返回碼。但是 Wait() 似乎扔掉了我還需要的剩余標準輸出。那么如何在 Cmd.Wait() 之后保留 os/exec.Cmd 的剩余標準輸出?示例代碼,使用 Unix bc 計算器命令:package mainimport (    "fmt"    "os/exec"    "bufio"    "io"    "time")func main() {    cmd := exec.Command("sh", "-c", "bc")    stdin, _ := cmd.StdinPipe()    stdout, _ := cmd.StdoutPipe()    scanner := bufio.NewScanner(stdout)    cmd.Start()    go func() {        cmd.Wait()        fmt.Println("finished")    }()    io.WriteString(stdin, "1 + 2\n")    fmt.Println(scanner.Scan(), scanner.Text())    io.WriteString(stdin, "3 + 4\n")    fmt.Println(scanner.Scan(), scanner.Text())    io.WriteString(stdin, "5 + 6\n")    io.WriteString(stdin, "quit\n")  // cmd.Wait() runs    time.Sleep(time.Second)    // Prints false :(    fmt.Println(scanner.Scan(), scanner.Text())}這打印: true 3 true 7 finished false我想:真 3 真 7 完成 真 11我還嘗試將 cmd.Stdout 設置為 bytes.Buffer,例如:    var buf bytes.Buffer    cmd.Stdout = &buf    scanner := bufio.NewScanner(&buf)但那是不可靠的。除非我用 time.Sleep() 添加延遲,否則它打印的都是假的。
查看完整描述

1 回答

?
紅顏莎娜

TA貢獻1842條經驗 獲得超13個贊

讀取到 stdout 末尾后調用 cmd.Wait()。


選項 1:在 scanner.Scan() 返回 false 后從主 goroutine 調用 cmd.Wait。


cmd := exec.Command("sh", "-c", "bc")

stdin, _ := cmd.StdinPipe()

stdout, _ := cmd.StdoutPipe()

scanner := bufio.NewScanner(stdout)

cmd.Start()


io.WriteString(stdin, "1 + 2\n")

fmt.Println(scanner.Scan(), scanner.Text())

io.WriteString(stdin, "3 + 4\n")

fmt.Println(scanner.Scan(), scanner.Text())

io.WriteString(stdin, "5 + 6\n")

io.WriteString(stdin, "quit\n") // cmd.Wait() runs

fmt.Println(scanner.Scan(), scanner.Text())

fmt.Println(scanner.Scan(), scanner.Text()) // prints false

cmd.Wait()

選項 2:從等待的 goroutine 中讀取:


cmd := exec.Command("sh", "-c", "bc")

stdin, _ := cmd.StdinPipe()

stdout, _ := cmd.StdoutPipe()

scanner := bufio.NewScanner(stdout)

cmd.Start()


var wg sync.WaitGroup

wg.Add(1)

go func() {

    for scanner.Scan() {

        fmt.Println(scanner.Text())

    }

    cmd.Wait()

    defer wg.Done()

}()


io.WriteString(stdin, "1 + 2\n")

io.WriteString(stdin, "3 + 4\n")

io.WriteString(stdin, "5 + 6\n")

io.WriteString(stdin, "quit\n") // cmd.Wait() runs

wg.Wait()


查看完整回答
反對 回復 2022-12-13
  • 1 回答
  • 0 關注
  • 170 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號