diff --git a/pkg/cluster/executor/local.go b/pkg/cluster/executor/local.go index 17d2937ce9..601847b9d4 100644 --- a/pkg/cluster/executor/local.go +++ b/pkg/cluster/executor/local.go @@ -42,9 +42,9 @@ var _ Executor = &Local{} func (l *Local) Execute(cmd string, sudo bool, timeout ...time.Duration) ([]byte, []byte, error) { // try to acquire root permission if l.Sudo || sudo { - cmd = fmt.Sprintf("sudo -H -u root bash -c \"cd; %s\"", cmd) + cmd = fmt.Sprintf("sudo -H -u root bash -c 'cd; %s'", cmd) } else { - cmd = fmt.Sprintf("sudo -H -u %s bash -c \"cd; %s\"", l.Config.User, cmd) + cmd = fmt.Sprintf("sudo -H -u %s bash -c 'cd; %s'", l.Config.User, cmd) } // set a basic PATH in case it's empty on login diff --git a/pkg/cluster/executor/local_test.go b/pkg/cluster/executor/local_test.go index c82ecfa568..d11a63c7d6 100644 --- a/pkg/cluster/executor/local_test.go +++ b/pkg/cluster/executor/local_test.go @@ -14,6 +14,7 @@ package executor import ( + "fmt" "io/ioutil" "os" "os/user" @@ -66,3 +67,27 @@ func TestWrongIP(t *testing.T) { assert.NotNil(err) assert.Contains(err.Error(), "not found") } + +func TestLocalExecuteWithQuotes(t *testing.T) { + assert := require.New(t) + user, err := user.Current() + assert.Nil(err) + local, err := New(SSHTypeNone, false, SSHConfig{Host: "127.0.0.1", User: user.Username}) + assert.Nil(err) + + deployDir, err := ioutil.TempDir("", "tiup-*") + assert.Nil(err) + defer os.RemoveAll(deployDir) + + cmds := []string{ + fmt.Sprintf(`find %s -type f -exec sed -i "s/\${DS_.*-CLUSTER}/hello/g" {} \;`, deployDir), + fmt.Sprintf(`find %s -type f -exec sed -i "s/DS_.*-CLUSTER/hello/g" {} \;`, deployDir), + `ls '/tmp'`, + } + for _, cmd := range cmds { + for _, sudo := range []bool{true, false} { + _, _, err = local.Execute(cmd, sudo) + assert.Nil(err) + } + } +}