Reputation: 26925
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\n", i)
} else {
fmt.Printf("STDOUT i: %d\n", 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 ?
Upvotes: 3
Views: 5045
Reputation:
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)
Upvotes: 3