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

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

如何在golang中使用os/exec處理用戶輸入?我無法停止輸入階段

如何在golang中使用os/exec處理用戶輸入?我無法停止輸入階段

Go
喵喵時光機 2023-07-17 17:12:54
首先,我將命令構建為 exec.exe:package mainimport "fmt"func main() {    var input string    fmt.Println("input a value")    fmt.Scanln(&input)    fmt.Println(input)    fmt.Println("input another value")    fmt.Scanln(&input)    fmt.Println(input)}然后我想使用 os/exec 包來運行它:package mainimport (    "fmt"    "os/exec")func main() {    cmd := exec.Command("G:\\go_workspace\\GOPATH\\src\\pjx\\modules\\exec\\exec")    stdin, e := cmd.StdinPipe()    if e != nil {        panic(e)    }    stdout, e := cmd.StdoutPipe()    if e != nil {        panic(e)    }    if e:=cmd.Start();e!=nil {        panic(e)    }    stdin.Write([]byte("hello"))    var buf = make([]byte, 512)    n, e := stdout.Read(buf)    if e != nil {        panic(e)    }    fmt.Println(string(buf[:n]))    if e := cmd.Wait(); e != nil {        panic(e)    }}最后我運行它,結果將在用戶輸入階段暫停,例如:(如果圖片未加載,它們會在輸入階段暫停)please input a value:112232我是否以錯誤的方式使用cmd管道?
查看完整描述

3 回答

?
海綿寶寶撒

TA貢獻1809條經驗 獲得超8個贊

該程序正在阻塞,因為子fmt.Scanln進程中的 正在等待該\n字符(anEOF也會導致它返回)。為了避免阻塞,您的輸入應該包含兩個\ns,或者您可以只調用“stdin.Close()”來指示輸入流已完成。


并且由于子流程多次調用Scanln和Println,因此單次調用stdout.Read可能無法讀取子流程的完整輸出。您可以繼續調用stdout.Read()直到io.EOF返回錯誤,或者只使用ioutil.ReadAll.


func main() {

    cmd := exec.Command("G:\\go_workspace\\GOPATH\\src\\pjx\\modules\\exec\\exec")


    stdin, e := cmd.StdinPipe()

    if e != nil {

        panic(e)

    }


    stdout, e := cmd.StdoutPipe()

    if e != nil {

        panic(e)

    }

    if e := cmd.Start(); e != nil {

        panic(e)

    }

    _, e = stdin.Write([]byte("hello\nworld\n"))

    if e != nil {

        panic(e)

    }

    stdin.Close()


    out, _ := ioutil.ReadAll(stdout)

    // or you can use a loop

    //for {

    //  var buf = make([]byte, 512)

    //  n, e := stdout.Read(buf)

    //  if e == io.EOF {

    //      break

    //  }

    //  if e != nil {

    //      panic(e)

    //  }

    //  fmt.Println(string(buf[:n]))

    //}


    fmt.Println(string(out))


    if e := cmd.Wait(); e != nil {

        panic(e)

    }

}


查看完整回答
反對 回復 2023-07-17
?
慕蓋茨4494581

TA貢獻1850條經驗 獲得超11個贊

一種方法可以做到這一點


cmd := exec.Command("...") // Change to your path

stdin, err := cmd.StdinPipe()

if err != nil {

    panic(err)

}

stdout, err := cmd.StdoutPipe()

if err != nil {

    panic(err)

}


buf := bytes.NewBuffer(nil)

// read the stdout continuously in a separate goroutine and capture it in buf

go func() {

    io.Copy(buf, stdout)

}()


if err := cmd.Start(); err != nil {

    panic(err)

}


stdin.Write([]byte("hello\n")) // Send \n to submit

stdin.Write([]byte("world\n"))


if err := cmd.Wait(); err != nil {

    panic(err)

}


fmt.Fprint(os.Stdout, buf)

結果:


? go run main.go

input a value

hello

input another value

world


查看完整回答
反對 回復 2023-07-17
?
陪伴而非守候

TA貢獻1757條經驗 獲得超8個贊

您需要監聽正在執行的程序的輸出。當您寫“hello”時,程序可能仍在寫入其標準輸出。嘗試這個:


    go func() {

        in := bufio.NewReader(stdout)

        for {

            s, err := in.ReadString('\n')

            if err != nil {

                return

            }

            fmt.Println(s)

        }

    }()


    if e := cmd.Start(); e != nil {

        panic(e)

    }


    stdin.Write([]byte("hello\n"))

    stdin.Write([]byte("hello2\n"))

    if e := cmd.Wait(); e != nil {

        panic(e)

    }


查看完整回答
反對 回復 2023-07-17
  • 3 回答
  • 0 關注
  • 216 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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