drasv0904 2016-07-06 16:59
浏览 131
已采纳

如何正确捕获所有标准输出/标准错误

I want to capture and save to a file all the stdout and stderr

For testing purposes I am printing only what I capture using this:

package main

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())
    }

}

The /tmp/stdout command can be build using this code:

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
", i)
        } else {
            fmt.Printf("STDOUT i: %d
", i)
        }
        time.Sleep(1 * time.Second)
    }

}

For some reason I am not been available to capture anything from the output, If I run the /tmp/stdout command I get this:

$ /tmp/stdout 
STDOUT i: 1
STDOUT i: 2
STDERR i: 3
STDOUT i: 4
STDOUT i: 5
STDERR i: 6
STDOUT i: 7

I was expecting to be available to get the same output while calling it from go with the previous code, the strange thing is that if I change to command to be something like id, whoami uname I do get the result and can printed, therefore wondering what could be wrong.

Any ideas ?

UPDATE

Found that I have to wait the program to finish, as suggested in the comments in order to get the output, but in case I would like to get the output in realtime how could I achieve this, what could be the best way of doing it, either io.Copy an os.Pipe, etc ?

  • 写回答

1条回答 默认 最新

  • dongzhao4036 2016-07-06 21:40
    关注

    but in case I would like to get the output in realtime

    One way to do that is to attach os.Stdout to cmd.Stdout

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

    Then you can use a File instead with f,_ := os.Create("file").

    If you want to write it to both a file and to the terminal at same time, i suspect (I have not done that yet), that you need to use io.Mutiwriters

    f, _ := os.Create("file")
    cmd.Stdout = io.MultiWriter(os.Stdout, f)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?