如何从Makefile中的.env文件加载和导出变量?

时间:2017-06-19 10:32:30

标签: makefile environment-variables

在Makefile中使用.env的最佳方法是什么,即加载该文件并导出make中子shell的所有变量?

如果建议的解决方案仅适用于make,例如,不使用任何第三方工具。此外.env个文件支持多行变量,如:

FOO="this\nis\na\nmultiline\nvar"

这就是this solution可能不够的原因。

1 个答案:

答案 0 :(得分:3)

Make不提供任何方法将文件内容读取到某个变量。因此,我认为不使用外部工具就无法实现结果。但是,如果我错了,我会很高兴学到一些新技巧。

因此,我们假设有两个文件.env,它们是技术上正确的shell文件:

FOO=bar

BAR="notfoo" # comment
   #comment
MULTILINE="This\nis\nSparta!"
# comment

script.sh

#!/bin/bash
echo FOO=${FOO}
echo BAR=${BAR}
echo -e ${MULTILINE}

一种解决方案是包含.env文件,然后确保导出变量:

include .env

$(eval export $(shell sed -ne 's/ *#.*$//; /./ s/=.*$$// p' .env))

all:
    ./script.sh

由于shell和make对引号的处理方式不同,您将在输出中看到引号。

您可以通过make:

重新处理变量来避免这种情况
include .env

VARS:=$(shell sed -ne 's/ *\#.*$$//; /./ s/=.*$$// p' .env )
$(foreach v,$(VARS),$(eval $(shell echo export $(v)="$($(v))")))

all:
    ./script.sh

然后多行变量变为单行。

最后,您可以生成一个临时文件,由bash处理并在运行任何命令之前将其获取:

SHELL=bash

all: .env-export
    . .env-export && ./script.sh

.env-export: .env
    sed -ne '/^export / {p;d}; /.*=/ s/^/export / p' .env > .env-export

哦,在这种情况下,多行变量中的新行被搞乱了。你需要另外引用它们。

最后,您可以使用上面的export命令将sed添加到.env,然后执行:

SHELL=bash
%: .env-export
    . .env-export && make -f secondary "$@"