Shell 使用 -ldflags 传递给 Go 编译器的字符串中的变量未展开
Shell variable in a string passed with -ldflags to the Go compiler is not expanded
我正在尝试让一个简单的构建 bash 脚本运行,但无法将日期作为参数。我在这里错过了什么?谢谢
#!/bin/bash
buildDate=$(date)
go build -ldflags='-X main.buildTimestamp=$buildDate' main.go
输出:Build: $buildDate
引用the documentation on a POSIX-compatible shell:
2.2.2 Single-Quotes
Enclosing characters in single-quotes ( ''
) shall preserve the literal value of each character within the single-quotes. A single-quote cannot occur within single-quotes.
因此,在您的特定情况下,bash
将 go build …
命令分解为单词并在实际执行命令之前执行字符串替换。
根据字符串替换规则,用单引号括起来的文本按字面意思,所以在扩展后 shell 查找 go
命令并执行它,将树结果参数传递给它,它们依次是:build
、-ldflags=-X main.buildTimestamp=$buildDate
和 main.go
.
由于 Go 工具链在其工作过程中不会在任何地方调用 shell,因此文字文本 $buildDate
会未经修改地传递给编译器。
如果构建日期的格式不包含空格,最简单的解决方法是将单引号替换为双引号。
如果你需要在其中嵌入空格,它会变得有点棘手,但不会太多——引用 go build help
:
的输出
The -asmflags
, -gccgoflags
, -gcflags
, and -ldflags
flags
accept a space-separated list of arguments to pass
to an underlying tool during the build.
To embed spaces in an element in the list, surround
it with either single or double quotes.
<…>
换句话说,命令行参数解析器考虑成对的 "
s 和 '
s 来实现参数分组,在你的情况下你可以做
go build -ldflags="-X main.buildTimestamp='$buildDate'" main.go
以便 shell 去除外部双引号 和 替换 $buildDate
为其值——根据大小写的字符串替换规则双引号。
因此,如果您的构建日期格式包含空格,例如 Tue, 12 May 2020 20:53:16 +0300
,go
命令将接收以下三个参数,顺序为:build
、-ldflags=-X main.buildTimestamp='Tue, 12 May 2020 20:53:16 +0300'
和main.go
,并且会自己处理那些单引号。
我正在尝试让一个简单的构建 bash 脚本运行,但无法将日期作为参数。我在这里错过了什么?谢谢
#!/bin/bash
buildDate=$(date)
go build -ldflags='-X main.buildTimestamp=$buildDate' main.go
输出:Build: $buildDate
引用the documentation on a POSIX-compatible shell:
2.2.2 Single-Quotes
Enclosing characters in single-quotes (
''
) shall preserve the literal value of each character within the single-quotes. A single-quote cannot occur within single-quotes.
因此,在您的特定情况下,bash
将 go build …
命令分解为单词并在实际执行命令之前执行字符串替换。
根据字符串替换规则,用单引号括起来的文本按字面意思,所以在扩展后 shell 查找 go
命令并执行它,将树结果参数传递给它,它们依次是:build
、-ldflags=-X main.buildTimestamp=$buildDate
和 main.go
.
由于 Go 工具链在其工作过程中不会在任何地方调用 shell,因此文字文本 $buildDate
会未经修改地传递给编译器。
如果构建日期的格式不包含空格,最简单的解决方法是将单引号替换为双引号。
如果你需要在其中嵌入空格,它会变得有点棘手,但不会太多——引用 go build help
:
The
-asmflags
,-gccgoflags
,-gcflags
, and-ldflags
flags accept a space-separated list of arguments to pass to an underlying tool during the build. To embed spaces in an element in the list, surround it with either single or double quotes. <…>
换句话说,命令行参数解析器考虑成对的 "
s 和 '
s 来实现参数分组,在你的情况下你可以做
go build -ldflags="-X main.buildTimestamp='$buildDate'" main.go
以便 shell 去除外部双引号 和 替换 $buildDate
为其值——根据大小写的字符串替换规则双引号。
因此,如果您的构建日期格式包含空格,例如 Tue, 12 May 2020 20:53:16 +0300
,go
命令将接收以下三个参数,顺序为:build
、-ldflags=-X main.buildTimestamp='Tue, 12 May 2020 20:53:16 +0300'
和main.go
,并且会自己处理那些单引号。