diff --git a/manager/command-prep.go b/manager/command-prep.go index d2a9ce17a..1403ef2b6 100644 --- a/manager/command-prep.go +++ b/manager/command-prep.go @@ -2,11 +2,33 @@ package manager +import ( + "os/exec" + "strings" +) + func prepCommand(command string) ([]string, error) { - if len(command) == 0 { + switch len(strings.Fields(command)) { + case 0: return []string{}, nil + case 1: + return []string{command}, nil + } + + // default to 'sh' on path, else try a couple common absolute paths + shell := "sh" + if _, err := exec.LookPath(shell); err != nil { + for _, sh := range []string{"/bin/sh", "/usr/bin/sh"} { + if sh, err := exec.LookPath(sh); err == nil { + shell = sh + break + } + } + } + if shell == "" { + return []string{}, exec.ErrNotFound } - cmd := []string{"sh", "-c", command} + cmd := []string{shell, "-c", command} return cmd, nil } diff --git a/manager/command-prep_windows.go b/manager/command-prep_windows.go index d78d85e12..31097bd9c 100644 --- a/manager/command-prep_windows.go +++ b/manager/command-prep_windows.go @@ -8,11 +8,11 @@ import ( ) func prepCommand(command string) ([]string, error) { - switch { - case len(command) == 0: + switch len(strings.Fields(command)) { + case 0: return []string{}, nil - case len(strings.Fields(command)) > 1: - return []string{}, fmt.Errorf("only single commands supported on windows") + case 1: + return []string{command}, nil } - return []string{command}, nil + return []string{}, fmt.Errorf("only single commands supported on windows") } diff --git a/manager/runner_test.go b/manager/runner_test.go index 31db31a16..65f8402ea 100644 --- a/manager/runner_test.go +++ b/manager/runner_test.go @@ -5,6 +5,8 @@ import ( "fmt" "io/ioutil" "os" + "os/exec" + "path/filepath" "reflect" "strings" "testing" @@ -1118,7 +1120,7 @@ func TestRunner_command(t *testing.T) { { name: "single", input: "echo", - parsed: []string{"sh", "-c", "echo"}, + parsed: []string{"echo"}, out: "\n", }, { @@ -1209,3 +1211,19 @@ func TestRunner_command(t *testing.T) { }) } } + +func TestRunner_commandPath(t *testing.T) { + PATH := os.Getenv("PATH") + defer os.Setenv("PATH", PATH) + os.Setenv("PATH", "") + cmd, err := prepCommand("echo hi") + if err != nil && err != exec.ErrNotFound { + t.Fatal(err) + } + if len(cmd) != 3 { + t.Fatalf("unexpected command: %#v\n", cmd) + } + if filepath.Base(cmd[0]) != "sh" { + t.Fatalf("unexpected shell: %#v\n", cmd) + } +}