如何在stdout / stderr中显示命令的输出,同时还将输出保存到Go中的变量中?

问题描述 投票:0回答:1

我认为我走在正确的轨道上,但是我的解决方案只是挂起并且无法在屏幕上打印任何内容,这是我在做什么错?

    r, w := io.Pipe()
    var stdout, stderr bytes.Buffer
    cmd.Stdout = w
    cmd.Stderr = &stderr
    tstdout := io.TeeReader(r, os.Stdout)
    tstderr := io.TeeReader(r, os.Stderr)
    io.Copy(&stdout, tstdout)
    io.Copy(&stderr, tstderr)

    err := cmd.Run()

    res := processResult{
        stderr.String(),
        stdout.Bytes(),
    }
go io pipe stdout stderr
1个回答
0
投票

您需要异步读取“ io.TeeReader”返回的阅读器。这是一个与我认为您要尝试执行的操作类似的示例。

package main

import (
    "bytes"
    "fmt"
    "io"
    "log"
    "os"
    "os/exec"
)

func main() {
    prout, pwout := io.Pipe()
    prerr, pwerr := io.Pipe()

    cmd := exec.Command("sh", "-c", "echo this is stdout; echo 1>&2 this is stderr")
    cmd.Stdout = pwout
    cmd.Stderr = pwerr

    tout := io.TeeReader(prout, os.Stdout)
    terr := io.TeeReader(prerr, os.Stderr)

    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }

    var bout, berr bytes.Buffer

    go func() {
        if _, err := io.Copy(&bout, tout); err != nil {
            log.Fatal(err)
        }
    }()

    go func() {
        if _, err := io.Copy(&berr, terr); err != nil {
            log.Fatal(err)
        }
    }()

    if err := cmd.Wait(); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("buffered out %s", bout.String())
    fmt.Printf("buffered err %s", berr.String())
}

输出为:

this is stdout
this is stderr
buffered out this is stdout
buffered err this is stderr

并且程序应运行完成并成功退出。

© www.soinside.com 2019 - 2024. All rights reserved.