github.com/safing/portbase@v0.19.5/utils/osdetail/command.go (about)

     1  package osdetail
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"os/exec"
     7  	"strings"
     8  )
     9  
    10  // RunCmd runs the given command and run error checks on the output.
    11  func RunCmd(command ...string) (output []byte, err error) {
    12  	// Create command to execute.
    13  	var cmd *exec.Cmd
    14  	switch len(command) {
    15  	case 0:
    16  		return nil, errors.New("no command supplied")
    17  	case 1:
    18  		cmd = exec.Command(command[0])
    19  	default:
    20  		cmd = exec.Command(command[0], command[1:]...)
    21  	}
    22  
    23  	// Create and assign output buffers.
    24  	var stdoutBuf bytes.Buffer
    25  	var stderrBuf bytes.Buffer
    26  	cmd.Stdout = &stdoutBuf
    27  	cmd.Stderr = &stderrBuf
    28  
    29  	// Run command and collect output.
    30  	err = cmd.Run()
    31  	stdout, stderr := stdoutBuf.Bytes(), stderrBuf.Bytes()
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	// Command might not return an error, but just write to stdout instead.
    36  	if len(stderr) > 0 {
    37  		return nil, errors.New(strings.SplitN(string(stderr), "\n", 2)[0])
    38  	}
    39  
    40  	// Debugging output:
    41  	// fmt.Printf("command stdout: %s\n", stdout)
    42  	// fmt.Printf("command stderr: %s\n", stderr)
    43  
    44  	// Finalize stdout.
    45  	cleanedOutput := bytes.TrimSpace(stdout)
    46  	if len(cleanedOutput) == 0 {
    47  		return nil, ErrEmptyOutput
    48  	}
    49  
    50  	return cleanedOutput, nil
    51  }