Add new "execpipe" package for easily streaming the output of commands in a sane, simple "io.Reader" way

This commit is contained in:
Tianon Gravi 2016-06-24 17:09:19 -07:00
parent d6068c47a7
commit 449c8e950c
1 changed files with 41 additions and 0 deletions

41
pkg/execpipe/execpipe.go Normal file
View File

@ -0,0 +1,41 @@
package execpipe
import (
"io"
"os/exec"
)
// "io.ReadCloser" interface to a command's output where "Close()" is effectively "Wait()"
type Pipe struct {
cmd *exec.Cmd
out io.ReadCloser
}
// convenience wrapper for "New"
func NewCommand(cmd string, args ...string) (*Pipe, error) {
return New(exec.Command(cmd, args...))
}
// start "cmd", capturing stdout in a pipe (be sure to call "Close" when finished reading to reap the process)
func New(cmd *exec.Cmd) (*Pipe, error) {
p := &Pipe{
cmd: cmd,
}
var err error
if p.out, err = p.cmd.StdoutPipe(); err != nil {
return nil, err
}
if err := p.cmd.Start(); err != nil {
p.out.Close()
return nil, err
}
return p, nil
}
func (pipe *Pipe) Read(p []byte) (n int, err error) {
return pipe.out.Read(p)
}
func (p *Pipe) Close() error {
return p.cmd.Wait()
}