diff --git a/pkg/util/exec/exec.go b/pkg/util/exec/exec.go index 7a2eda26b25..23c2a268523 100644 --- a/pkg/util/exec/exec.go +++ b/pkg/util/exec/exec.go @@ -21,6 +21,9 @@ import ( "syscall" ) +// ErrExecutableNotFound is returned if the executable is not found. +var ErrExecutableNotFound = osexec.ErrNotFound + // Interface is an interface that presents a subset of the os/exec API. Use this // when you want to inject fakeable/mockable exec behavior. type Interface interface { @@ -81,13 +84,17 @@ func (cmd *cmdWrapper) SetDir(dir string) { func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) { out, err := (*osexec.Cmd)(cmd).CombinedOutput() if err != nil { - ee, ok := err.(*osexec.ExitError) - if !ok { - return out, err + if ee, ok := err.(*osexec.ExitError); ok { + // Force a compile fail if exitErrorWrapper can't convert to ExitError. + var x ExitError = &exitErrorWrapper{ee} + return out, x } - // Force a compile fail if exitErrorWrapper can't convert to ExitError. - var x ExitError = &exitErrorWrapper{ee} - return out, x + if ee, ok := err.(*osexec.Error); ok { + if ee.Err == osexec.ErrNotFound { + return out, ErrExecutableNotFound + } + } + return out, err } return out, nil } diff --git a/pkg/util/exec/exec_test.go b/pkg/util/exec/exec_test.go index 49a432b36da..d24f9cc1935 100644 --- a/pkg/util/exec/exec_test.go +++ b/pkg/util/exec/exec_test.go @@ -92,3 +92,12 @@ func TestLookPath(t *testing.T) { t.Errorf("unexpected result for LookPath: got %s, expected %s", sh, shExpected) } } + +func TestExecutableNotFound(t *testing.T) { + exec := New() + cmd := exec.Command("fake_executable_name") + _, err := cmd.CombinedOutput() + if err != ErrExecutableNotFound { + t.Errorf("Expected error ErrExecutableNotFound but got %v", err) + } +}