execpipe.go 859 B

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. package execpipe
  2. import (
  3. "io"
  4. "os/exec"
  5. )
  6. // "io.ReadCloser" interface to a command's output where "Close()" is effectively "Wait()"
  7. type Pipe struct {
  8. cmd *exec.Cmd
  9. out io.ReadCloser
  10. }
  11. // convenience wrapper for "Run"
  12. func RunCommand(cmd string, args ...string) (*Pipe, error) {
  13. return Run(exec.Command(cmd, args...))
  14. }
  15. // start "cmd", capturing stdout in a pipe (be sure to call "Close" when finished reading to reap the process)
  16. func Run(cmd *exec.Cmd) (*Pipe, error) {
  17. pipe := &Pipe{
  18. cmd: cmd,
  19. }
  20. if out, err := pipe.cmd.StdoutPipe(); err != nil {
  21. return nil, err
  22. } else {
  23. pipe.out = out
  24. }
  25. if err := pipe.cmd.Start(); err != nil {
  26. pipe.out.Close()
  27. return nil, err
  28. }
  29. return pipe, nil
  30. }
  31. func (pipe *Pipe) Read(p []byte) (n int, err error) {
  32. return pipe.out.Read(p)
  33. }
  34. func (pipe *Pipe) Close() error {
  35. return pipe.cmd.Wait()
  36. }