如何处理stderr?

时间:2014-07-08 17:40:27

标签: go

我有一个名为“myapp”的应用。该应用程序只是写入stderr。

重要的是,我想捕获stderr中写入的内容并实时处理它。我该怎么做呢?

我尝试了下面的代码。 :

cmd := exec.Command("myapp") // this app prints lines to stderr
stderr, err := cmd.StderrPipe()
if err != nil {
    log.Fatal(err)
}

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

if b, err := ioutil.ReadAll(stderr); err == nil {
    log.Println(string(b))
}                                                                                                       

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

代码不打印任何内容。我怀疑这是因为ioutil.ReadAll()不是正确的函数,因为它等待EOF。我怎么从stderr管道读取?

您可以将输出的命令替换为输出到stdout或stderr的任何内容,例如tail -f mylogfile。关键是,我想在将它们写入stdout时处理这些行。

2 个答案:

答案 0 :(得分:4)

StderrPipe返回ReadCloser。您可以使用它来创建bufio.Scanner,然后逐个读取行:

sc := bufio.NewScanner(stderr)
for sc.Scan() {
    fmt.Printf("Line: %s\n", sc.Text());
}

答案 1 :(得分:1)

创建一个实现io.Writer的类型,并将其设置为command's stderr writer。

type Processor struct{}

func (Processor) Write(b []byte) (int, error) {
    // intercept data here
    return os.Stdout.Write(b)
}

func main() {
    cmd := exec.Command("mycommand")
    cmd.Stderr = Processor{}
    _ = cmd.Run()
}