Skip to content

Instantly share code, notes, and snippets.

@nodirt
Last active January 25, 2018 02:48
Show Gist options
  • Save nodirt/9ae282ddfc735654d4e9 to your computer and use it in GitHub Desktop.
Save nodirt/9ae282ddfc735654d4e9 to your computer and use it in GitHub Desktop.
Reading from both stdout and stderr in one func
package main
import (
"bytes"
"fmt"
"io"
"os/exec"
)
// RunAndListen intercepts cmd.Stdout and cmd.Stderr and runs cmd.
func RunAndListen(cmd *exec.Cmd, listener func(line string, stderr bool) error) error {
out := func(data []byte, stderr bool) (n int, err error) {
buf := bytes.NewBuffer(data)
for {
line, err := buf.ReadString('\n')
if err == io.EOF {
break
}
if err == nil {
err = listener(line, stderr)
}
if err != nil {
return len(data) - buf.Len(), err
}
}
return len(data), nil
}
cmd.Stdout = WriterFunc(func(data []byte) (int, error) {
return out(data, false)
})
cmd.Stderr = WriterFunc(func(data []byte) (int, error) {
return out(data, true)
})
return cmd.Run()
}
func main() {
cmd := exec.Command("cat", "main.go", "nonexistent.go")
RunAndListen(cmd, func(line string, stderr bool) error {
if stderr {
fmt.Print("err: ")
}
fmt.Print(line)
return nil
})
}
type WriterFunc func([]byte) (n int, err error)
func (f WriterFunc) Write(data []byte) (n int, err error) {
return f(data)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment