package util import ( "bytes" "fmt" "log" "os/exec" "strings" ) // Run executes a command and returns stdout and stderr. func Run(args ...string) (string, string, error) { cmd := exec.Command(args[0], args[1:]...) var sout bytes.Buffer var serr bytes.Buffer cmd.Stdout = &sout cmd.Stderr = &serr err := cmd.Run() return sout.String(), serr.String(), err } func RunOrDie(args ...string) string { log.Printf("util about to run %s", PrettyCmd(args)) sout, serr, err := Run(args...) if err != nil { log.Fatalf("Error running %v: %v\nstdout:\n%v\nstderr:\n%v", args, err, sout, serr) } return sout } // PrettyCmd formats a broken up shell command for human readability. // Example 1: ["ls", "/var"] --> ls /var // Example 2: ["echo", "hello world"] --> echo "hello world" func PrettyCmd(args []string) string { chunks := make([]string, len(args)) for i, arg := range args { if strings.Contains(arg, " ") { chunks[i] = fmt.Sprintf(`"%s"`, arg) } else { chunks[i] = arg } } return strings.Join(chunks, " ") }