github.com/docker-library/go-dockerlibrary@v0.0.0-20200821205225-669fbe5c1d52/pkg/execpipe/execpipe.go (about)

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