猿问

exec,Cmd.Run() 没有正确运行带参数的命令

go version go1.15.6 windows/amd64 dev os Windows [版本 10.0.19041.630]


我有一个 Go 应用程序,我在其中使用 exec.Cmd.Run() 运行 AWS CLI。我构建了 Cmd 类并填充了参数。


在运行 Cmd 之前,我使用 .String() 方法查看要运行的命令。如果我采用此值,将其复制到 shell,则命令执行时不会对提供给我的输出进行任何修改,也不会报告任何问题。


但是,当我运行该命令时,它无法返回错误。当我调试脚本时,它失败了,因为它说 AWS CLI 说参数不正确。


问题:


是否可以看到正在运行的内容的 100% 原始表示?它与 .String() 的返回值不匹配

有没有更好的方法来调用我缺少的操作系统级别命令?

真实例子:


cmd := &exec.Cmd{

    Path:   awsPath,

    Args:   args,

    Stdout: &stdout,

    Stderr: &stderr,

}


fmt.Printf("Command: %s\n", cmd.String())

// c:\PROGRA~1\Amazon\AWSCLIV2\aws.exe --profile testprofile --region us-east-1 --output json ec2 describe-network-interfaces --filters Name=group-id,Values=sg-abc123

// Running above works 100% of the time if ran from a shell window


err := cmd.Run()

// always errors out saying the format is incorrect

GoPlayground 复制问题 https://play.golang.org/p/mvV9VG8F0oz


一只甜甜圈
浏览 178回答 2
2回答

犯罪嫌疑人X

从cmd.String来源:// String returns a human-readable description of c.// It is intended only for debugging.// In particular, it is not suitable for use as input to a shell.// The output of String may vary across Go releases.您看到的是相反的情况,但问题是相同的:目测打印的命令字符串不会显示确切的可执行路径(是否存在流氓空格或不可打印的字符?),与参数(流氓字符?)相同。用于fmt.Printf("cmd : %q\n", cmd.Path)显示任何隐藏的 unicode 字符等。并对每个参数使用相同的技术。

蝴蝶不菲

我找到了您遇到的问题的根本原因:os/exec// Path is the path of the command to run.//// This is the only field that must be set to a non-zero// value. If Path is relative, it is evaluated relative// to Dir.Path string// Args holds command line arguments, including the command as **Args[0]**.// If the Args field is empty or nil, Run uses {Path}.//// In typical use, both Path and Args are set by calling Command.Args []string因此,如果您已声明Cmd.Path := "/usr/local/bin/aws",则必须像这样声明Cmd. Args:Args:   []string{"", "s3", "help"},因为Args包含上述文档链接中的命令Args[0]。最后,我认为您可以简单有效地执行这样的命令:package mainimport (    "bytes"    "fmt"    "os/exec")func main() {    stdout := &bytes.Buffer{}    stderr := &bytes.Buffer{}    name := "/usr/local/bin/aws"    arg := []string{"s3", "help"}    cmd := exec.Command(name, arg...)    cmd.Stderr = stderr    cmd.Stdout = stdout    fmt.Printf("Command: %q\n", cmd.String())    err := cmd.Run()    if err != nil {        fmt.Println("Error: ", stderr.String())    }    fmt.Println("Output: ", stdout.String())}=========$ go run main.goCommand: "/usr/local/bin/aws s3 help"完毕。
随时随地看视频慕课网APP

相关分类

Go
我要回答