air-verse / air

☁️ Live reload for Go apps
GNU General Public License v3.0
16.39k stars 773 forks source link

cmd 命令双引号问题 #501

Open zhaojunliing opened 7 months ago

zhaojunliing commented 7 months ago

cmd = 'go build -gcflags="all=-N -l" -o ./tmp/main.exe .'

我在windows平台进行开发,启动cmd命令需要使用双引号,这个直接执行会出现

invalid value "\"all=-N" for flag -gcflags: parameter may not start with quote character " usage: go build [-o output] [build flags] [packages] Run 'go help build' for details. 转义的错误

zhaojunliing commented 7 months ago

我修改了util_windows.go

package runner

import (
    "io"
    "os/exec"
    "strconv"
    "strings"
)

func (e *Engine) killCmd(cmd *exec.Cmd) (pid int, err error) {
    pid = cmd.Process.Pid
    // https://stackoverflow.com/a/44551450
    kill := exec.Command("TASKKILL", "/T", "/F", "/PID", strconv.Itoa(pid))
    return pid, kill.Run()
}

func (e *Engine) startCmd(cmd string) (*exec.Cmd, io.ReadCloser, io.ReadCloser, error) {
    var err error

    args := append([]string{"/c"}, parseCmdString(cmd)...)
    if !strings.Contains(cmd, ".exe") {
        e.runnerLog("CMD will not recognize non .exe file for execution, path: %s", cmd)
    }
    c := exec.Command("cmd", args...)
    stderr, err := c.StderrPipe()
    if err != nil {
        return nil, nil, nil, err
    }
    stdout, err := c.StdoutPipe()
    if err != nil {
        return nil, nil, nil, err
    }
    err = c.Start()
    if err != nil {
        return nil, nil, nil, err
    }
    return c, stdout, stderr, err
}

func parseCmdString(cmdString string) []string {
    var parts []string
    var tmpParts []string

    flag := true
    for _, arg := range strings.Fields(cmdString) {
        if !flag || strings.Contains(arg, "\"") {
            arg = strings.Replace(arg, "\"", "", -1)
            tmpParts = append(tmpParts, arg)
            if flag {
                flag = false
            } else {
                flag = true
                parts = append(parts, strings.Join(tmpParts, " "))
                tmpParts = []string{}
            }
        } else if flag {
            parts = append(parts, arg)
        }
    }
    return parts
}

增加parseCmdString方法,会将引号引起来的命令拼接到一个数组里面,并删除双引号,测试是可以执行的

zhaojunliing commented 7 months ago

还有个疑问,在goland启用远程调试的时候,air热部署会让远程调试中断,需要手动进行点击重新调试,这种情况怎么处理 @xiantang ,还有air不开发了吗

dalefengs commented 5 months ago

可以暂时使用 powershell 执行解决 cmd = "powershell.exe go build -gcflags 'all=-N -l' -o ./tmp/main.exe ."