diff --git a/zshell/shell.go b/zshell/shell.go index e7c1da3..116fd1e 100644 --- a/zshell/shell.go +++ b/zshell/shell.go @@ -305,16 +305,33 @@ func CallbackRunContext(ctx context.Context, command string, callback func(out s } func fixCommand(command string) (runCommand []string) { - tmp := "" - for _, v := range strings.Split(command, " ") { - if strings.HasSuffix(v, "\\") { - tmp += v[:len(v)-1] + " " - } else { - if tmp != "" { - v = tmp + v - tmp = "" + var current []rune + quoted := false + quoteType := '\000' + escaped := false + for i, c := range command { + if escaped { + current = append(current, c) + escaped = false + } else if c == '\\' { + escaped = true + } else if c == '"' || c == '\'' { + if quoted && c == quoteType { + quoted = false + quoteType = '\000' + } else if !quoted { + quoted = true + quoteType = c } - runCommand = append(runCommand, v) + } else if c == ' ' && !quoted { + runCommand = append(runCommand, string(current)) + current = nil + } else { + current = append(current, c) + } + + if i == len(command)-1 { + runCommand = append(runCommand, string(current)) } } return diff --git a/zshell/shell_test.go b/zshell/shell_test.go index b398ef5..c6d1a68 100644 --- a/zshell/shell_test.go +++ b/zshell/shell_test.go @@ -100,3 +100,20 @@ func TestCallbackRun(t *testing.T) { tt.NoError(err) tt.Log("code", <-code) } + +func Test_fixCommand(t *testing.T) { + tt := zlsgo.NewTest(t) + + e := []string{"ping", "www.npmjs.com"} + r := fixCommand("ping www.npmjs.com") + tt.Equal(e, r) + + e = []string{"ls", "-a", "/Applications/Google Chrome.app"} + r = fixCommand("ls -a /Applications/Google\\ Chrome.app") + tt.Equal(e, r) + + e = []string{"networksetup", "-setwebproxystate", "USB 10/100/1000 LAN", "on"} + r = fixCommand(`networksetup -setwebproxystate "USB 10/100/1000 LAN" on`) + tt.Equal(e, r) + +}