登录
首页 >  Golang >  Go问答

在终端中运行二进制文件并实时查看输出

来源:stackoverflow

时间:2024-02-25 12:18:25 224浏览 收藏

本篇文章给大家分享《在终端中运行二进制文件并实时查看输出》,覆盖了Golang的常见基础知识,其实一个语言的全部知识点一篇文章是不可能说完的,但希望通过这些问题,让读者对自己的掌握程度有一定的认识(B 数),从而弥补自己的不足,更好的掌握它。

问题内容

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

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()
}

如果我想要实现的目标是可能的,有什么想法吗?


正确答案


正如 @mgagnon 提到的,你的问题可能出在其他地方;就像外部依赖项可能只是由于不在终端中运行而失效一样。使用以下命令来模拟 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。为了简洁起见,还使用扫描仪。

将其用作我的 /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[:])
   }
}

理论要掌握,实操不能落!以上关于《在终端中运行二进制文件并实时查看输出》的详细介绍,大家都掌握了吧!如果想要继续提升自己的能力,那么就来关注golang学习网公众号吧!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>