bash 中的间接变量设置可以像所以:
#!/bin/bash
foo=bar
ind=foo
echo ${!ind} # prints `bar'
尝试与 (GNU) Makefile 配方一样运行
# Makefile
test:
foo=bar
ind=foo
echo $$\{!ind\}
echo $${!ind}
无论是否转义{}
字符都会失败,并显示以下消息:
foo=bar
ind=foo
echo $\{!ind\}
${!ind}
echo ${!ind}
/bin/sh: 1: Bad substitution
/tmp/Makefile:2: recipe for target 'test' failed
make: *** [test] Error 2
问题可能是 Makefile 的特殊字符丢失/错误转义。
或者它可能是变量扩展的顺序/时间,请参阅make的二次扩展。
有任何想法吗?
如果重要的话,这是 bash4.4.12(1)-release
和 makeGNU Make 4.1
答案1
你们真是太不可思议了。在我发布问题后不到十分钟,您就引导我找到了正确的解决方案,即:
# Makefile
SHELL=/bin/bash
test:
foo=bar; \
ind=foo; \
echo $${!ind}
谢谢 Steeldriver,谢谢 Choroba。
答案2
这里有两个问题:
- 用于菜谱的默认 shell 是 a
sh
,因此您需要使用SHELL=/bin/bash
菜谱才能理解类似语法${!ind}
- 配方中的每一行都由单独的 shell 执行,因此,如果您在配方中定义变量,则同一配方的下一行会丢失该变量。这是通过
.ONESHELL
特殊目标解决的
所以工作示例如下所示:
# Makefile
.ONESHELL:
SHELL=/bin/bash
test:
foo=bar
ind=foo
echo $$\{!ind\}
echo $${!ind}
有关更详细(和官方)的解释,请访问 https://www.gnu.org/software/make/manual/make.html#Execution