Bash 与-ldflags一起传递给Go编译器的字符串中的Shell变量未展开

Bash 与-ldflags一起传递给Go编译器的字符串中的Shell变量未展开,bash,go,quoting,Bash,Go,Quoting,我正在尝试让一个简单的buildbash脚本工作,但无法将日期作为参数。我错过了什么?谢谢 #!/bin/bash buildDate=$(date) go build -ldflags='-X main.buildTimestamp=$buildDate' main.go 输出:Build:$buildDate引用: 2.2.2单引号 用单引号('')括起的字符应保留单引号内每个字符的文字值。单引号不能出现在单引号内 因此,在您的特定情况下,bash将go build…命令分解为单词,并在实

我正在尝试让一个简单的buildbash脚本工作,但无法将日期作为参数。我错过了什么?谢谢

#!/bin/bash
buildDate=$(date)
go build -ldflags='-X main.buildTimestamp=$buildDate' main.go
输出:
Build:$buildDate
引用:

2.2.2单引号

用单引号(
''
)括起的字符应保留单引号内每个字符的文字值。单引号不能出现在单引号内

因此,在您的特定情况下,
bash
go build…
命令分解为单词,并在实际执行该命令之前执行字符串替换

根据字符串替换规则,用单引号括起来的文本按字面意思表示,因此在扩展之后,shell将查找
go
命令并执行它,并将树结果参数传递给它,这些参数的顺序是:
build
-ldflags=-X main.buildTimestamp=$buildDate
main.go

由于Go工具链在其工作过程中不会在任何地方调用shell,因此文本
$buildDate
将不经修改地传递给编译器

如果构建日期的格式不包含空格,最简单的修复方法就是用双引号替换单引号

如果您需要在其中嵌入空格,它会变得有点棘手,但不会太多-引用
go build help
的输出:

-asmlags
-gccgolfags
-gcflags
-ldflags
标志 接受以空格分隔的要传递的参数列表 在构建过程中添加到基础工具。 要在列表中的元素中嵌入空格,请环绕 它可以用单引号或双引号表示。

换句话说,命令行参数解析器考虑成对的
来实现参数分组,在您的情况下,您可以这样做

go build -ldflags="-X main.buildTimestamp='$buildDate'" main.go
因此,shell去掉外部双引号,并根据双引号情况下的字符串替换规则,用
$buildDate
替换其值。

因此,如果您的构建日期格式包含空格,例如,
Tue,2020年5月12日20:53:16+0300
go
命令将接收以下三个参数,顺序为:
build
-ldflags=-X main.buildTimestamp='Tue,2020年5月12日20:53:16+0300'
main.go
,并将处理这些si单引号本身。

谢谢!在将单引号替换为双引号后执行脚本,并获得go build的命令参数列表。1)如果生成日期字符串包含空格,则可能会遇到更复杂的问题;2)我建议首先在shell提示符中手动执行调用。Ineed,日期输出为spaces。将其更改为日期-u+%Y-%m-%d-%H:%m并成功。谢谢!@Adrian,我倾向于认为这个问题仍然值得使用
go
标签,因为工具链在处理传递给
-*flags
的参数中的空格时有一定的怪癖,我在回答中提到了这一点。你是对的,这对其他地鼠同伴来说很方便。补充道.