【问题标题】:Can a process read its own "standard out" stream?进程可以读取自己的“标准输出”流吗?
【发布时间】:2019-08-06 04:03:57
【问题描述】:

进程如何读取自己的输出流?我正在编写自动化测试,它在与测试相同的过程中启动一些应用程序子过程(应用程序)。因此,标准输出是测试输出和应用程序输出的混合。

我想在运行时读取输出流,如果我看到来自应用程序的错误,则测试失败。这可能/可行吗?如果是这样,我该怎么做?

注意:我知道我可以将应用程序作为它们自己的独立进程启动,然后读取它们的输出流。我现在的工作量很大。

另外请注意,这不是 How to test a function's output (stdout/stderr) in Go unit tests 的骗子,尽管这张票是相似且有用的。另一张票是关于捕获单个函数调用的输出。这张票是关于连续阅读整个流的。正确答案也有点不同——它需要一个管道。

【问题讨论】:

  • 我不认为这是一个骗局,尽管它相似且有用。谢谢你指点我!另一张票是关于捕获单个函数调用的输出。在这里,我想连续阅读整个流。
  • 解决方法是一样的。毕竟,每个程序都只是一个main() 函数。
  • 解决方法类似,但不一样。另一种解决方案具有明确的开始/停止,而这是连续流式传输。此外,另一个解决方案在函数结束后得到输出。我想要一个单独的线程同时执行。
  • Go 不公开线程,所以这不是一个真正的选择。

标签: multithreading go output outputstream


【解决方案1】:

是的,你可以使用os.Pipe()然后自己处理:

tmp := os.Stdout
r, w, err := os.Pipe()
if err != nil {
    panic(err)
}
os.Stdout = w

或将os.Stdout 转移到另一个文件或strings.Builder
以下是详细答案:
In Go, how do I capture stdout of a function into a string?

【讨论】:

    【解决方案2】:

    使用os.PipeIPC 的一种形式)对In Go, how do I capture stdout of a function into a string? 中给出的答案稍作修改:

    Pipe 返回一对连接的文件;从 r 读取返回写入 w 的字节。它返回文件和错误(如果有)。

    由于os.Stdout*os.File,您可以将其替换为任何 文件。

     package main
    
     import (
        "bytes"
        "fmt"
        "io"
        "log"
        "os"
     )
    
     func main() {
        old := os.Stdout
        r, w, _ := os.Pipe() // TODO: handle error.
        os.Stdout = w
    
        // All stdout will be caputered from here on.
    
        fmt.Println("this will be caputered")
    
        // Access output and restore previous stdout.
        outc := make(chan string)
    
        go func() {
            var buf bytes.Buffer
            io.Copy(&buf, r) // TODO: handle error
            outc <- buf.String()
        }()
    
        w.Close()
        os.Stdout = old
    
        out := <-outc
        log.Printf("captured: %s", out)
     }
    

    【讨论】:

      猜你喜欢
      • 2012-08-05
      • 2016-03-26
      • 2012-12-20
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 2011-02-17
      相关资源
      最近更新 更多