如何将.env环境变量传递到Makefile目标的子命令中?
问题描述
我有一段无法修改的Python代码(不能使用dotenv库):
MONGODB_SETTINGS = { "connect": False, "port": int(os.environ.get("MONGODB_DB_PORT", 27017)), "db": os.environ.get("MONGODB_DB_NAME", "foo"), "host": os.environ.get("MONGODB_HOST", "127.0.0.1"), "authentication_source": os.environ.get("MONGODB_AUTHSRC", "admin"), "username": os.environ.get("MONGODB_USERNAME"), "password": os.environ.get("MONGODB_PASSWORD"), }
同时有如下Makefile:
... admin: ## Equals to create an admin echo $(MONGODB_DB_PORT) @ flask admin ...
以及.env文件:
MONGODB_DB_PORT=27018
我已经在Makefile顶部加入include .env,但环境变量无法传递到目标的子命令中,执行flask admin时数据库端口还是默认的27017。由于.env里有多个环境变量,没法逐个处理,请问怎么把.env中的变量传递到Makefile目标的子命令里?
解决方案
Makefile里用include .env只是把.env内容加载成Makefile变量,不会自动传递给子进程。要把这些变量注入子命令环境,有两种实用方法:
方法一:批量导出变量到子环境
在Makefile顶部include .env之后,添加一行:
export
这会把所有Makefile变量(包括从.env加载的)导出到后续子命令的环境中,执行make admin时flask admin就能读取到MONGODB_DB_PORT等变量。
如果只想导出.env里的变量(避免导出其他Makefile变量),可以用以下命令提取并导出:
include .env # 过滤注释行,提取.env中的变量名并逐个导出 $(foreach v,$(shell grep -v '^#' .env | cut -d= -f1),$(eval export $(v)))
方法二:执行子命令前加载.env
修改Makefile的admin目标,在执行flask admin前加载.env的变量:
admin: ## Equals to create an admin echo $(MONGODB_DB_PORT) @ env $(shell grep -v '^#' .env | xargs) flask admin
或者用更简洁的shell原生写法(依赖POSIX shell的.命令,和source等价):
admin: ## Equals to create an admin echo $(MONGODB_DB_PORT) @ . .env && flask admin
这种方式会在当前shell环境中先加载.env变量,再运行flask admin,确保命令能读取到所有.env中的配置。
内容的提问来源于stack exchange,提问作者Emad Helmi
相关产品推荐
相关产品推荐

