【发布时间】:2016-07-06 16:59:17
【问题描述】:
我想捕获所有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 = 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 命令可以使用以下代码构建:
package main
import (
"fmt"
"os"
"time"
)
func main() {
for i := 1; i < 1000; i++ {
if i%3 == 0 {
fmt.Fprintf(os.Stderr, "STDERR i: %d\n", i)
} else {
fmt.Printf("STDOUT i: %d\n", i)
}
time.Sleep(1 * time.Second)
}
}
由于某种原因,我无法从输出中捕获任何内容,如果我运行 /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 我会这样做得到结果并可以打印,因此想知道可能出了什么问题。
有什么想法吗?
更新
发现我必须等待程序完成,如 cmets 中建议的那样才能获得输出,但如果我想实时获得输出,我该如何实现这一点,最好的方法是什么这样做,io.Copy 和 os.Pipe 等等?
【问题讨论】:
-
你真的等了 1000 秒让
/tmp/stdout完成吗?请注意,cmd.Wait()将阻止您的程序,直到命令完成运行。 -
尝试使用 go-logging stackoverflow.com/questions/38208608/…
-
尝试将
os.Stdout与fmt.Fprintf结合使用,以保持简单,但如果您想要更专业的解决方案,则不要使用已经建议的日志记录。 -
你考虑过
go run main.go &> out+err.txt吗?编辑 nvm 我没有意识到你是从 go 调用子进程