Go 如何正确捕获所有stdout/stderr

Go 如何正确捕获所有stdout/stderr,go,stdout,stderr,Go,Stdout,Stderr,我想捕获所有数据并保存到文件中 出于测试目的,我仅打印使用以下方法捕获的内容: 包干管 import ( "bufio" "bytes" "fmt" "io" "os/exec" ) func main() { cmd := exec.Command("/tmp/stdout") stdout := new(bytes.Buffer) stderr := new(bytes.Buffer) cmd.Stdout = st

我想捕获所有数据并保存到文件中

出于测试目的,我仅打印使用以下方法捕获的内容:

包干管

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

func main() {
    cmd := exec.Command("/tmp/stdout")
    stdout := new(bytes.Buffer)
    stderr := new(bytes.Buffer)

    cmd.Stdout = stdout
    cmd.Stderr = stderr

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

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

    in := bufio.NewScanner(io.MultiReader(stdout, stderr))
    for in.Scan() {
        fmt.Println(in.Text())
    }

}
可以使用以下代码生成/tmp/stdout命令:

主程序包
进口(
“fmt”
“操作系统”
“时间”
)
func main(){
对于i:=1;i<1000;i++{
如果i%3==0{
fmt.Fprintf(os.Stderr,“Stderr i:%d\n”,i)
}否则{
fmt.Printf(“标准输出i:%d\n”,i)
}
时间。睡眠(1*时间。秒)
}
}
由于某些原因,我无法从输出中捕获任何内容,如果我运行
/tmp/stdout
命令,我会得到以下结果:

$ /tmp/stdout 
STDOUT i: 1
STDOUT i: 2
STDERR i: 3
STDOUT i: 4
STDOUT i: 5
STDERR i: 6
STDOUT i: 7
我希望在使用前面的代码从go调用时可以获得相同的输出,奇怪的是,如果我将命令更改为类似于
id
whoami
uname
的内容,我确实得到了结果,并且可以打印出来,因此想知道可能出了什么问题

有什么想法吗

更新

发现我必须按照注释中的建议等待程序完成才能获得输出,但如果我想实时获得输出,如何实现这一点,最好的方法是什么,或者
io.Copy
an
os.Pipe
,等等

但如果我想得到实时输出

一种方法是将
os.Stdout
附加到
cmd.Stdout

oCmd := exec.Command(bin, cmdArgs...)
oCmd.Stdout = os.Stdout
oCmd.Stderr = os.Stderr

err := oCmd.Run()
然后您可以将文件改为使用
f,:=os.Create(“文件”)

如果您想同时将其写入文件和终端,我怀疑(我还没有这样做),您需要使用
io.multiwriters

f, _ := os.Create("file")
cmd.Stdout = io.MultiWriter(os.Stdout, f)

您是否真的等了1000秒才完成
/tmp/stdout
?请注意,
cmd.Wait()
将阻止您的程序,直到命令完成运行。请尝试使用go日志记录,尝试将
os.Stdout
fmt.Fprintf
组合,以保持简单,但如果您想要更专业的解决方案,您是否考虑过
go run main.go&>out+err.txt
?编辑nvm我没有意识到您正在从goThanks调用子进程,但我认为我需要使用gorutines,如果我想处理而不需要等待,例如,我想预解析输出,而不是直接将其发送到文件,如go中的logger.afaik,你必须创造一个作家,做一个作家中的作家。cmd.Stdout->write->parser->write->os.Stdout。关于goroutines,只需执行一个
go func(done chan){}
。这有一些模式。