我有一个 Makefile,其中一个目标创建一个.env
文件,该文件在另一个目标中读取。因此,由于该文件是动态创建的,因此我不能将include
其放在 Makefile 的顶部。export
我尝试了使用和 的方法xargs
,如此处所述,但它不起作用。这是我的 Makefile:
create_dotenv_file:
echo "FOO=BAR" > .env
test_env: create_dotenv_file
export $(cat .env | xargs) && \
echo $(FOO)
这就是我执行时得到的结果$ make test_env
:
/home# make test_env
echo "FOO=BAR" > .env
export && \
echo
我缺少什么?
这里有几个问题:
该表达式
$(cat .env | xargs)
没有达到您的预期。命令make
本身用于$
变量扩展;这意味着make
正在解释该表达式,而不是 shell。它make
看起来像是对无效变量的引用,因此替换是空字符串。同样,
$(FOO)
指的是不存在的make
变量。FOO
您需要替换
$
为$$
才能让 shell 看到单个$
.Makefile 目标中的每一行都在新的 shell 中执行。即使您的
export $(cat .env|xargs)
语句有效,它也是无操作的——环境变量的更改只会影响当前进程及其子进程。您实际上正在启动一个新的 shell,设置一个环境变量,然后退出该 shell;你的环境变量丢失了。您可以
Makefile
通过执行以下操作来重写您的代码,使其“有效”:但这仍然是有问题的。上面设置了两个变量并按预期工作,但是如果其中一个变量包含空格,会发生什么情况,例如:
你最终会得到 shell 表达式:
因此,您将拥有
FOO=This
、BAR=a
和几个名为is
和 的空环境变量test
。更有效的解决方案可能如下所示:
这用于
set -a
启用export
我们创建或修改的所有变量;然后.
读取该.env
文件,然后set +a
禁用set -a
.make test_env
上面运行的输出Makefile
是:但即使使用该解决方案,它可能仍然无法满足您的要求...目标中的变量在
test_env
其他任何地方都无法使用,因为设置环境变量只会影响当前进程及其子进程。在 shell 脚本中导出变量根本无法使它们在Makefile
.