登录
首页 >  Golang >  Go问答

如何将 -ldflags 传递给具有多个参数的 exec.Command

来源:stackoverflow

时间:2024-04-10 17:33:34 181浏览 收藏

哈喽!今天心血来潮给大家带来了《如何将 -ldflags 传递给具有多个参数的 exec.Command》,想必大家应该对Golang都不陌生吧,那么阅读本文就都不会很困难,以下内容主要涉及到,若是你正在学习Golang,千万别错过这篇文章~希望能帮助到你!

问题内容

我有一个相当简单的 go 文件,它构建了几个用 go 编写的内部工具。它运行良好,直到我决定将 -ldflags 添加到我的构建命令中。以下是格式化 go build 命令的代码片段。

var cmd *exec.cmd
file := fmt.sprintf("%s.%s.%s", p.bin, e.os, e.arch)
if len(p.flags) > 0 {
    ldflags := ""
    for _, f := range p.flags {
        if len(ldflags) > 0 {
            ldflags = ldflags + " "
        }
        ldflags = ldflags + f.flag
    }
    ldflags = "\"" + ldflags + "\""
    fmt.println("go", "build", "-v", "-a", "-ldflags", ldflags, "-o", fmt.sprintf("/tmp/bin/%s", file), ".")
    cmd = exec.command("go", "build", "-a", "-ldflags", ldflags, "-o", fmt.sprintf("/tmp/bin/%s", file), ".")
} else {
    fmt.println("go", "build", "-v", "-a", "-o", fmt.sprintf("/tmp/bin/%s", file), ".")
    cmd = exec.command("go", "build", "-a", "-o", fmt.sprintf("/tmp/bin/%s", file), ".")
        }
cmd.dir = p.pkg
cmd.stdout = ioutil.discard
cmd.stderr = os.stdout
cmd.env = append(cleanenv(),
    fmt.sprintf("goos=%s", e.os),
    fmt.sprintf("goarch=%s", e.arch),
)

if err := cmd.run(); err != nil {
    return err
}

我的标志被定义为像这样的简单字符串

[]flagarg{
    {flag:"-x main.buildstamp=`date -u '+%y-%m-%d_%i:%m:%s%p'`"},
    {flag:"-x main.githash=`git rev-parse --short head`"},
}

以下是我打印时的输出

go build -v -a -ldflags "-X main.buildstamp=`date -u
'+%Y-%m-%d_%I:%M:%S%p'` -X main.githash=`git rev-parse --short HEAD`"
-o /tmp/bin/bro.linux.amd64 .

当我将上面的命令粘贴到 cli 中时,它可以工作,但当我通过 go 脚本运行此 go build 时,它会失败。当我说失败时,我的意思是它没有设置我的变量 githashbuildstamp。复制并粘贴命令确实按预期设置了这些变量。

我认为这一定是带有引号的东西,我已经尝试改变它们,但我无法让事情正常工作。我开始认为我正走在错误的道路上,这一定是一个更好的方法来实现这一目标。


解决方案


问题可能出在 command substitution (backticks) 上;它没有执行您期望的操作,因为它是 shell 的一项功能,而不是“go build”命令。

[]flagarg{
    {flag:"-x main.buildstamp=`date -u '+%y-%m-%d_%i:%m:%s%p'`"},
    // bash command subst ----^------------------------------^

尝试将打印的命令行作为“bash -c”的单个字符串参数执行,例如:

cmd = exec.command("bash", "-c", "go build -v -a ...")

您可能还想考虑使用 $(...) 形式的 bash 命令替换(我认为它更容易阅读),这里有一个简单的示例来演示:

cmdline := "echo \"The time is now '$(date)'!\""
out, err := exec.Command("bash", "-c", cmdline).Output()
if err != nil {
    panic(err)
}
fmt.Println(string(out))
// The time is now 'Tue Aug 28 09:33:34 MDT 2018'!

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>