执行命令行二进制文件并持续读取标准输出

在 Go 中,我想从我的应用程序中执行一个二进制文件,并不断读取命令打印到 stdout 的内容。但是,需要注意的是,二进制文件被编程为无限执行其任务,直到它读取回车键,而我无法访问二进制文件的源代码。如果我直接从终端执行二进制文件,它的行为是正确的。但是,如果我从应用程序内执行二进制文件,它会以某种方式认为它读取了 enter 键,并且几乎立即关闭。下面是一个代码片段,演示了我如何尝试执行二进制文件,将其标准化,然后将其打印到屏幕上:


func main() {

    // The binary that I want to execute.

    cmd := exec.Command("/usr/lib/demoApp")


    // Pipe the command's output.

    stdout, err := cmd.StdoutPipe()

    if err != nil {

        fmt.Println(err)

    }

    stdoutReader := bufio.NewReader(stdout)


    // Start the command.

    err = cmd.Start()

    if err != nil {

        fmt.Println(err)

    }


    // Read and print the command's output.

    buff := make([]byte, 1024)

    var n int

    for err == nil {

        n, err = stdoutReader.Read(buff)

        if n > 0 {

            fmt.Printf(string(buff[0:n]))

        }

    }

    _ = cmd.Wait()

}

任何想法,如果我试图完成的事情是可能的?


jeck猫
浏览 140回答 2
2回答

喵喔喔

你的问题可能出在其他地方;就像也许外部依赖只是由于不在终端中运行而保释。使用以下内容来模拟:demoAppfunc main() {    fmt.Println("Press enter to exit")    // Every second, report fake progress    go func() {        for {            fmt.Print("Doing stuff...\n")            time.Sleep(time.Second)        }    }()    for {        // Read single character and if enter, exit.        consoleReader := bufio.NewReaderSize(os.Stdin, 1)        input, _ := consoleReader.ReadByte()        // Enter = 10 | 13 (LF or CR)        if input == 10 || input == 13 {            fmt.Println("Exiting...")            os.Exit(0)        }    }}...这对我来说很好:func main() {    cmd := exec.Command("demoApp.exe")    stdout, err := cmd.StdoutPipe()    if err != nil {        panic(err)    }    stdin, err := cmd.StdinPipe()    if err != nil {        log.Fatal(err)    }    go func() {        defer stdin.Close()        // After 3 seconds of running, send newline to cause program to exit.        time.Sleep(time.Second * 3)        io.WriteString(stdin, "\n")    }()    cmd.Start()    // Scan and print command's stdout    scanner := bufio.NewScanner(stdout)    for scanner.Scan() {        fmt.Println(scanner.Text())    }    // Wait for program to exit.    cmd.Wait()}$ go run main.goPress enter to exitDoing stuff...Doing stuff...Doing stuff...Exiting...这与你的代码之间的唯一区别是,我使用stdin在3秒后发送换行符来终止cmd。也使用扫描仪为简洁。

桃花长相依

用这个作为我的:/usr/lib/demoApppackage mainimport (   "fmt"   "time")func main() {   for {      fmt.Print("North East South West")      time.Sleep(time.Second)   }}此程序按预期工作:package mainimport (   "os"   "os/exec")func main() {   cmd := exec.Command("demoApp")   stdout, err := cmd.StdoutPipe()   if err != nil {      panic(err)   }   cmd.Start()   defer cmd.Wait()   for {      var b [1024]byte      stdout.Read(b[:])      os.Stdout.Write(b[:])   }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go