首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将os.Stdout重定向到Go中的io.MultiWriter()?

如何将os.Stdout重定向到Go中的io.MultiWriter()?
EN

Stack Overflow用户
提问于 2022-04-09 19:19:25
回答 2查看 587关注 0票数 1

我正在编写一个测试函数,用于测试go程序与命令行程序的交互。那是

os.Stdio -> cmd.Stdin

cmd.Stdin -> os.Stdin

我可以用管道连接这些io,但是我会有一条传递管道的数据日志。我尝试使用io.MultiWriter,但它不是os.file对象,不能分配给os.Stdout。我发现了一些使用大量管道和io.copy的样品。但由于io.copy不具有交互性。如何用管道将Stdout连接到io.MultiWriter?

代码语言:javascript
运行
复制
logfile, err := os.Create("stdout.log")
r, w, _ := os.Pipe()
mw := io.MultiWriter(os.Stdout, logfile, w)
cmd.Stdin = r
os.Stdout = mw // <- error in this line

错误消息,如

代码语言:javascript
运行
复制
cannot use mw (variable of type io.Writer) as type *os.File in assignment:
EN

回答 2

Stack Overflow用户

发布于 2022-04-10 12:16:00

作为另一种解决方案,您可以使用单独的func来模拟MultiWriter,以读取已写入stdout的内容,捕获它,然后将其写入文件和原始stdout

代码语言:javascript
运行
复制
package main

import (
    "bufio"
    "fmt"
    "os"
    "time"
)

func main() {
    originalStdout := os.Stdout //Backup of the original stdout
    r, w, _ := os.Pipe()
    os.Stdout = w

    //Use a separate goroutine for non-blocking
    go func() {
        f, _ := os.Create("stdout.log")
        defer f.Close()
        scanner := bufio.NewScanner(r)
        for scanner.Scan() {
            s := scanner.Text() + "\r\n"
            f.WriteString(s)
            originalStdout.WriteString(s)
        }
    }()

    //Test
    c := time.NewTicker(time.Second)
    for {
        select {
        case <-c.C:
            fmt.Println(time.Now())
            fmt.Fprintln(os.Stderr, "This is on Stderr")
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2022-04-11 04:59:31

我用管道、TeeReader和MultiWriter完成了一项工作。安装是一个测试函数,它通过stdin和stdout测试go程序与python程序的交互。

main.stdout -> pipe -> TeeReader-> (client.stdin,MultiWriter(log,stdout))

client.stdout -> MultiWriter(管道-> main.stdin,logfile,stdout )

稍后我将尝试添加更多的解释。

代码语言:javascript
运行
复制
func Test_Interactive(t *testing.T) {
    var tests = []struct {
        file string
    }{
        {"Test_Client.py"},
    }
    for tc, tt := range tests {
        fmt.Println("---------------------------------")
        fmt.Printf("Test %d, Test Client:%v\n", tc+1, tt.file)
        fmt.Println("---------------------------------")
        // Define external program
        client := exec.Command("python3", tt.file)
        // Define log file
        logfile, err := os.Create(tt.file + ".log")
        if err != nil {
            panic(err)
        }
        defer logfile.Close()
        out := os.Stdout
        defer func() { os.Stdout = out }() // Restore original Stdout
        in := os.Stdin
        defer func() { os.Stdin = in }() // Restore original Stdin

        // Create pipe connect os.Stdout to client.Stdin
        gr, gw, _ := os.Pipe()

        // Connect os.Stdout to writer side of pipe
        os.Stdout = gw

        // Create MultiWriter to write to logfile and os.Stdout at the same time
        gmw := io.MultiWriter(out, logfile)

        // Create a tee reader read from reader side of the pipe and flow to the MultiWriter
        // Repleace the cmd.Stdin with TeeReader

        client.Stdin = io.TeeReader(gr, gmw)

        // Create a pipe to connect client.Stdout to os.Stdin
        cr, cw, _ := os.Pipe()

        // Create MultWriter to client stdout
        cmw := io.MultiWriter(cw, logfile, out)
        client.Stdout = cmw

        // Connect os stdin to another end of the pipe
        os.Stdin = cr

        // Start Client
        client.Start()
        // Start main
        main()
        // Check Testing program error
        if err := client.Process.Release(); err != nil {
            if exiterr, ok := err.(*exec.ExitError); ok {
                if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
                    log.Printf("Exit Status: %d", status.ExitStatus())
                    t.Errorf("Tester return error\n")
                }
            } else {
                log.Fatalf("cmd.Wait: %v", err)
                t.Errorf("Tester return error\n")
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71811175

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档