在字符串中进行变量替换
Make variable substitution in string
假设我定义了一个 json 文件:
foo.json
:
{"key":"${VALUE}"}
makefile:
export VALUE=bar
SHELL=/usr/bin/env bash
foo=$(shell cat foo.json)
bar:
@echo "$(foo)"
问题是:如何通过 make 的变量替换或 echo
的 BASH 替换来扩展 ${VALUE}
,以便在有效的 JSON 文件中使用双引号保留在 OUTPUT 上(是的,make 保留了它们,是的,echo $(foo)
也计算了变量——但去掉了双引号——是的,我不关心换行符掉线)?
至于这一切的原因,假设我有一个例程需要一个相当于一种语言(而不是配置)的富有表现力的 JSON 文件,并且我正在使用 Make 来控制系统:
.PHONY: generator
# in the language of control theory
generator: $(foreach q,${Qm},.Qmarked-startup-$q)
application $@ -i <(pseudo code: {envsubst $@.json})
.Qmarked-startup-%: $(pseudo code: q0 dependencies ... )
# $* here is a verb
application $* -i <(pseudo code: {envsubst $*.json})
如果你 运行 这个 Makefile :
export VALUE=bar
SHELL=/usr/bin/env bash
foo=$(shell cat foo.json)
bar:
$(warning $(foo))
你可以看到 $(foo) 确实包含双引号。但是 $VALUE 没有展开。
你可以试试这个:
export VALUE=bar
SHELL=/usr/bin/env bash
foo=$(shell VALUE=$(VALUE) envsubst < foo.json)
bar:
@echo '${foo}'
如果你想从 Make 的环境中扩展变量,你可以使用 eval
来扩展赋值内部的变量。
假设您不介意按照@MadScientists 的评论将所有行分类在一起,您可以 grep 出评论并将 json 合并为一行,如下所示:
export VALUE:=bar
foo:=$(shell grep -v "^\S*//" foo.json)
$(info foo=[$(foo)])
$(eval foo2:=$(shell grep -v "^\S*//" foo.json))
$(info foo2=[$(foo2)])
bar:
@echo "from recipe: foo2=[$(subst ",\",$(foo2))]"
$(subst ",\",...)
在发送到 bash 之前转义引号。这输出:
foo=[{"key":"${VALUE}"}]
foo2=[{"key":"bar"}]
from recipe: foo2=[{"key":"bar"}]
注意:出于安全考虑——如果外部人员可以访问 foo.json,那么他们可以使用制造商的权限来制造 运行 任何他们想要的东西。
假设我定义了一个 json 文件:
foo.json
:
{"key":"${VALUE}"}
makefile:
export VALUE=bar
SHELL=/usr/bin/env bash
foo=$(shell cat foo.json)
bar:
@echo "$(foo)"
问题是:如何通过 make 的变量替换或 echo
的 BASH 替换来扩展 ${VALUE}
,以便在有效的 JSON 文件中使用双引号保留在 OUTPUT 上(是的,make 保留了它们,是的,echo $(foo)
也计算了变量——但去掉了双引号——是的,我不关心换行符掉线)?
至于这一切的原因,假设我有一个例程需要一个相当于一种语言(而不是配置)的富有表现力的 JSON 文件,并且我正在使用 Make 来控制系统:
.PHONY: generator
# in the language of control theory
generator: $(foreach q,${Qm},.Qmarked-startup-$q)
application $@ -i <(pseudo code: {envsubst $@.json})
.Qmarked-startup-%: $(pseudo code: q0 dependencies ... )
# $* here is a verb
application $* -i <(pseudo code: {envsubst $*.json})
如果你 运行 这个 Makefile :
export VALUE=bar
SHELL=/usr/bin/env bash
foo=$(shell cat foo.json)
bar:
$(warning $(foo))
你可以看到 $(foo) 确实包含双引号。但是 $VALUE 没有展开。
你可以试试这个:
export VALUE=bar
SHELL=/usr/bin/env bash
foo=$(shell VALUE=$(VALUE) envsubst < foo.json)
bar:
@echo '${foo}'
如果你想从 Make 的环境中扩展变量,你可以使用 eval
来扩展赋值内部的变量。
假设您不介意按照@MadScientists 的评论将所有行分类在一起,您可以 grep 出评论并将 json 合并为一行,如下所示:
export VALUE:=bar
foo:=$(shell grep -v "^\S*//" foo.json)
$(info foo=[$(foo)])
$(eval foo2:=$(shell grep -v "^\S*//" foo.json))
$(info foo2=[$(foo2)])
bar:
@echo "from recipe: foo2=[$(subst ",\",$(foo2))]"
$(subst ",\",...)
在发送到 bash 之前转义引号。这输出:
foo=[{"key":"${VALUE}"}]
foo2=[{"key":"bar"}]
from recipe: foo2=[{"key":"bar"}]
注意:出于安全考虑——如果外部人员可以访问 foo.json,那么他们可以使用制造商的权限来制造 运行 任何他们想要的东西。