为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
jeck猫 2022-09-12 17:06:39
在 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()}任何想法,如果我试图完成的事情是可能的?
查看完整描述

2 回答

?
喵喔喔

TA贡献1735条经验 获得超5个赞

你的问题可能出在其他地方;就像也许外部依赖只是由于不在终端中运行而保释。使用以下内容来模拟:demoApp


func 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.go

Press enter to exit

Doing stuff...

Doing stuff...

Doing stuff...

Exiting...

这与你的代码之间的唯一区别是,我使用stdin在3秒后发送换行符来终止cmd。也使用扫描仪为简洁。


查看完整回答
反对 回复 2022-09-12
?
桃花长相依

TA贡献1860条经验 获得超8个赞

用这个作为我的:/usr/lib/demoApp


package main


import (

   "fmt"

   "time"

)


func main() {

   for {

      fmt.Print("North East South West")

      time.Sleep(time.Second)

   }

}

此程序按预期工作:


package main


import (

   "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[:])

   }

}


查看完整回答
反对 回复 2022-09-12
  • 2 回答
  • 0 关注
  • 134 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信