diff --git a/libs/exec/exec.go b/libs/exec/exec.go index f3e777a4230..4bec8b21b45 100644 --- a/libs/exec/exec.go +++ b/libs/exec/exec.go @@ -42,7 +42,7 @@ type command struct { func (c *command) Wait() error { // After the command has finished (cmd.Wait call), remove the temporary script file - defer os.Remove(c.execContext.scriptFile) + defer c.execContext.cleanup() err := c.cmd.Wait() if err != nil { @@ -140,7 +140,7 @@ func (e *Executor) Exec(ctx context.Context, command string) ([]byte, error) { if err != nil { return nil, err } - defer os.Remove(ec.scriptFile) + defer ec.cleanup() return cmd.CombinedOutput() } diff --git a/libs/exec/exec_test.go b/libs/exec/exec_test.go index 49ab2eba664..da4fe37f803 100644 --- a/libs/exec/exec_test.go +++ b/libs/exec/exec_test.go @@ -117,7 +117,11 @@ func TestExecutorNoShellFound(t *testing.T) { } func TestExecutorCleanupsTempFiles(t *testing.T) { - executor, err := NewCommandExecutor(".") + if runtime.GOOS != "windows" { + t.Skipf("cmd.exe is not available on non-Windows systems") + } + + executor, err := NewCommandExecutorWithExecutable(".", CmdExecutable) assert.NoError(t, err) cmd, ec, err := executor.prepareCommand(context.Background(), "echo 'Hello'") @@ -126,7 +130,8 @@ func TestExecutorCleanupsTempFiles(t *testing.T) { command, err := executor.start(cmd, ec) assert.NoError(t, err) - fileName := ec.args[1] + fileName := ec.scriptFile + assert.NotEmpty(t, fileName) assert.FileExists(t, fileName) err = command.Wait() diff --git a/libs/exec/shell.go b/libs/exec/shell.go index ee29eac8a0b..77c690467bd 100644 --- a/libs/exec/shell.go +++ b/libs/exec/shell.go @@ -14,9 +14,19 @@ type shell interface { type execContext struct { executable string args []string + + // scriptFile is the file that contains the command to be executed. + // We only use it for the cmd.exe shell since cmd.exe does not support + // inlining scripts. scriptFile string } +func (e *execContext) cleanup() { + if e.scriptFile != "" { + os.Remove(e.scriptFile) + } +} + func findShell() (shell, error) { for _, fn := range []func() (shell, error){ newBashShell, diff --git a/libs/exec/shell_bash.go b/libs/exec/shell_bash.go index 9f6b508f4d6..b030887a3e4 100644 --- a/libs/exec/shell_bash.go +++ b/libs/exec/shell_bash.go @@ -11,15 +11,9 @@ type bashShell struct { } func (s bashShell) prepare(command string) (*execContext, error) { - filename, err := createTempScript(command, ".sh") - if err != nil { - return nil, err - } - return &execContext{ executable: s.executable, - args: []string{"-e", filename}, - scriptFile: filename, + args: []string{"-c", command}, }, nil } diff --git a/libs/exec/shell_execv_test.go b/libs/exec/shell_execv_test.go index 580053b46c4..1e76f74dc48 100644 --- a/libs/exec/shell_execv_test.go +++ b/libs/exec/shell_execv_test.go @@ -4,21 +4,20 @@ import ( "os/exec" "testing" - "github.com/databricks/cli/internal/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestShellExecvOpts(t *testing.T) { - newOpts, err := shellExecvOpts("echo hello", "/a/b/c", []string{"key1=value1", "key2=value2"}) + opts, err := shellExecvOpts("echo hello", "/a/b/c", []string{"key1=value1", "key2=value2"}) require.NoError(t, err) - assert.Equal(t, []string{"key1=value1", "key2=value2"}, newOpts.Env) - assert.Equal(t, "/a/b/c", newOpts.Dir) + assert.Equal(t, []string{"key1=value1", "key2=value2"}, opts.Env) + assert.Equal(t, "/a/b/c", opts.Dir) bashPath, err := exec.LookPath("bash") require.NoError(t, err) - assert.Equal(t, bashPath, newOpts.Args[0]) - assert.Equal(t, "-e", newOpts.Args[1]) - assert.Equal(t, "echo hello", testutil.ReadFile(t, newOpts.Args[2])) + assert.Equal(t, bashPath, opts.Args[0]) + assert.Equal(t, "-c", opts.Args[1]) + assert.Equal(t, "echo hello", opts.Args[2]) } diff --git a/libs/exec/shell_sh.go b/libs/exec/shell_sh.go index ca42ecfa465..a09d8ed7d36 100644 --- a/libs/exec/shell_sh.go +++ b/libs/exec/shell_sh.go @@ -10,15 +10,9 @@ type shShell struct { } func (s shShell) prepare(command string) (*execContext, error) { - filename, err := createTempScript(command, ".sh") - if err != nil { - return nil, err - } - return &execContext{ executable: s.executable, - args: []string{"-e", filename}, - scriptFile: filename, + args: []string{"-c", command}, }, nil }