In Go, how do I capture stdout of a function into a string?

后端 未结 4 560
庸人自扰
庸人自扰 2020-11-28 06:13

In Python, for example, I can do the following:

realout = sys.stdout
sys.stdout = StringIO.StringIO()
some_function() # prints to stdout get captured in the          


        
4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-28 06:47

    I don't recommend this, but you can achieve it with altering os.Stdout. Since this variable is of type os.File, your temporary output should also be a file.

    package main
    
    import (
        "fmt"
        "io/ioutil"
        "os"
        "path/filepath"
    )
    
    func print() {
        fmt.Println("output")
    }
    
    func main() {
        // setting stdout to a file
        fname := filepath.Join(os.TempDir(), "stdout")
        fmt.Println("stdout is now set to", fname)
        old := os.Stdout // keep backup of the real stdout
        temp, _ := os.Create(fname) // create temp file
        os.Stdout = temp
    
        print()
    
        // back to normal state
        temp.Close()
        os.Stdout = old // restoring the real stdout
    
        // reading our temp stdout
        fmt.Println("previous output:")
        out, _ := ioutil.ReadFile(fname)
        fmt.Print(string(out))
    }
    

    I don't recommend because this is too much hacking, and not very idiomatic in Go. I suggest passing an io.Writer to the functions and writing outputs to that. This is the better way to do almost the same thing.

    package main
    
    import (
        "bytes"
        "fmt"
        "io"
        "os"
    )
    
    func print(w io.Writer) {
        fmt.Fprintln(w, "output")
    }
    
    func main() {
        fmt.Println("print with byes.Buffer:")
        var b bytes.Buffer
        print(&b)
        fmt.Print(b.String())
    
        fmt.Println("print with os.Stdout:")
        print(os.Stdout)
    }
    

提交回复
热议问题