为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
一只甜甜圈 2022-07-18 16:42:36
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 windowerr := cmd.Run()// always errors out saying the format is incorrectGoPlayground 复制问题 https://play.golang.org/p/mvV9VG8F0oz
查看完整描述

2 回答

?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

从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 字符等。并对每个参数使用相同的技术。


查看完整回答
反对 回复 2022-07-18
?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

我找到了您遇到的问题的根本原因: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 main


import (

    "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.go

Command: "/usr/local/bin/aws s3 help"

完毕。


查看完整回答
反对 回复 2022-07-18
  • 2 回答
  • 0 关注
  • 177 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号