bitbucket.org/ai69/amoy@v0.2.3/exec_run.go (about)

     1  package amoy
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"os/exec"
     7  	"strings"
     8  
     9  	sp "bitbucket.org/creachadair/shell"
    10  	"github.com/1set/gut/yos"
    11  )
    12  
    13  var (
    14  	errInvalidCommand  = errors.New("invalid command")
    15  	errMissingProcInfo = errors.New("missing process info")
    16  )
    17  
    18  // RunQuietCommand runs the command quietly and returns no standard output nor standard error.
    19  func RunQuietCommand(command string) error {
    20  	cmd, err := parseSingleRawCommand(command)
    21  	if err != nil {
    22  		return err
    23  	}
    24  	return cmd.Run()
    25  }
    26  
    27  // RunCombinedCommand runs the command and returns its combined standard output and standard error.
    28  func RunCombinedCommand(command string) ([]byte, error) {
    29  	if cmd, err := parseSingleRawCommand(command); err != nil {
    30  		return nil, err
    31  	} else if out, err := cmd.CombinedOutput(); err != nil {
    32  		return nil, err
    33  	} else {
    34  		return out, nil
    35  	}
    36  }
    37  
    38  // RunSimpleCommand simply runs the command and returns its standard output and standard error.
    39  func RunSimpleCommand(command string) ([]byte, []byte, error) {
    40  	cmd, err := parseSingleRawCommand(command)
    41  	if err != nil {
    42  		return nil, nil, err
    43  	}
    44  
    45  	var (
    46  		bufOut bytes.Buffer
    47  		bufErr bytes.Buffer
    48  	)
    49  	cmd.Stdout = &bufOut
    50  	cmd.Stderr = &bufErr
    51  	err = cmd.Run()
    52  	return bufOut.Bytes(), bufErr.Bytes(), err
    53  }
    54  
    55  /*
    56  RunPipeCommand(cmd)
    57  RunCommand(cmd, envs, timeout)
    58  */
    59  
    60  func parseSingleRawCommand(raw string) (*exec.Cmd, error) {
    61  	// HACK: workaround for escape issue of creachadair/shell on Windows
    62  	if yos.IsOnWindows() {
    63  		raw = strings.ReplaceAll(raw, `\`, `\\`)
    64  	}
    65  
    66  	if parts, ok := sp.Split(raw); !ok {
    67  		return nil, errInvalidCommand
    68  	} else if _, err := exec.LookPath(parts[0]); err != nil {
    69  		return nil, err
    70  	} else {
    71  		return exec.Command(parts[0], parts[1:]...), nil
    72  	}
    73  }