// Package shell is a tiny wrapper around os/exec for running external // commands with a context (timeout/cancellation). package shell import ( "bytes" "context" "fmt" "os/exec" ) // Run executes name with args, using ctx for timeout/cancellation. It returns // the combined standard output on success. On a non-zero exit (or spawn // failure) it returns an error that includes the captured standard error. func Run(ctx context.Context, name string, args ...string) (string, error) { cmd := exec.CommandContext(ctx, name, args...) var stdout, stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr if err := cmd.Run(); err != nil { return stdout.String(), fmt.Errorf("%s: %w: %s", name, err, stderr.String()) } return stdout.String(), nil }