给定一个带有变量
DB_USER=foo@bar
的 .env 文件,对于 Makefile:
.ONESHELL:
SHELL:=/bin/bash
all:
set -o allexport;source .env ;set +o allexport && echo $(DB_USER)
和
$ make all
$ set -o allexport;source .env ;set +o allexport && echo
在终端工作中测试这一点:
$ set -o allexport;source .env ;set +o allexport; && echo $DB_USER
$ foo@bar
如何在 makefile 中解决这个问题?
将
echo $(DB_USER)
更改为 echo $$DB_USER
。
然后:
$ cat Makefile
.ONESHELL:
SHELL:=/bin/bash
all:
set -o allexport;source .env ;set +o allexport && echo $$DB_USER
$ cat .env
DB_USER=Me
$ make
set -o allexport;source .env ;set +o allexport && echo $DB_USER
Me
为什么?
配方在父级为
make
的 shell 中运行。 $(DB_USER)
指的是 make-variable
在 make's
环境中未定义。 $DB_USER
是对变量的引用
在子 shell 的环境中,您已在 .env
文件中设置了该环境
相同的 shell,因此您可以引用它。子进程无法推送环境
变量进入其父级,即使可以,也是毫无意义的:它只是
正在运行需要该值的 shell。
您需要在菜谱上下文中将
$DB_USER
转义为 $$DB_USER
,
否则 make
将在菜谱之前展开 $DB_USER
= $(D)B_USER
= B_USER
甚至是运行。 GNU Make 手册:6.1 变量引用基础知识
美元符号后跟美元符号以外的字符、左括号 或开括号将该单个字符视为变量名。这样,您就可以 用‘$x’引用变量x。然而,这种做法可能会导致混乱......
同样,你总是需要在食谱上下文中像
$shellvar
一样转义$$shellvar
。