You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Makefile中动态加载.env系列配置文件的环境变量值

问题根源
  1. Make 默认将目标的每一行命令放在独立的子 Shell 进程中执行,source 命令仅对当前行的子进程生效,执行完就会销毁,无法跨行、跨目标共享。
  2. Make 的变量展开发生在解析阶段,而目标依赖的执行发生在解析完成后的运行阶段,因此无法在运行阶段生成 .env 后,再让 Make 反向解析其中的变量给后续目标使用,除非调整执行逻辑。

可行实现方案

方案一:单 Shell 模式动态加载(推荐,适合多环境动态切换)

依赖 GNU Make 3.82+ 版本的 .ONESHELL 特性,能让同一个目标的所有命令运行在同一个 Shell 进程,配合过滤注释的加载逻辑,完美匹配需求:

# 开启单shell模式,同一个目标的所有命令在同一个shell进程执行
.ONESHELL:
# 统一使用bash作为shell,支持更丰富的语法
SHELL := /bin/bash

# env-% 目标负责合并通用配置和环境专属配置,生成.env文件
env-%:
	@echo "Getting $* env"
	cat .env-common > .env
	@echo >> .env
	cat .env-$* >> .env
	@echo >> .env
	@cat .env

# 通用.env加载函数,自动过滤#开头的注释和空行
define load_env
	@echo "Loading .env contents into shell"
	while IFS= read -r line; do
		export "$$line"
	done < <(grep -v '^#' .env | grep -v '^$$')
endef

# 业务目标示例
something-else-%: env-%
	$(call load_env)
	# 后续命令可以直接读取所有环境变量
	echo $$SOMETHING_FROM_COMMON
	echo $$SOMETHING_FROM_DEV
	# 你的docker build等业务逻辑直接使用变量即可

使用方法:直接执行 make something-else-dev 即可,变量支持包含空格等特殊字符,兼容注释。


方案二:全局加载变量到 Make 上下文(适合变量跨多个独立目标共享)

如果需要变量在所有目标中都可以通过 Make 原生语法 $(变量名) 直接调用,可以用 Include 规则配合自动生成 .env 的逻辑,解决 Include 找不到文件的问题:

# 默认环境,可通过执行参数覆盖
ENV ?= dev
ENV_FILE := .env

# 声明.env文件的生成规则
$(ENV_FILE):
	@echo "Getting $(ENV) env"
	cat .env-common > $(ENV_FILE)
	@echo >> $(ENV_FILE)
	cat .env-$(ENV) >> $(ENV_FILE)
	@echo >> $(ENV_FILE)

# 自动加载.env,不存在时先生成再加载
ifeq ($(wildcard $(ENV_FILE)),)
$(shell make $(ENV_FILE) ENV=$(ENV))
endif
# 过滤注释行后导入
include $(shell grep -v '^#' $(ENV_FILE) | grep -v '^$$' | sed 's/^/ /' > .env.tmp && echo .env.tmp)
# 导出所有变量到子进程
export

# 业务目标示例
something-else:
	echo $(SOMETHING_FROM_COMMON)
	echo $(SOMETHING_FROM_DEV)

使用方法:执行 make something-else ENV=dev 指定环境,所有目标都可以直接用 $(变量名) 读取加载好的环境变量。


注意事项
  • 方案二切换环境时需要先删除旧的 .env 文件,可以新增清理目标:
.PHONY: clean-env
clean-env:
	rm -f .env .env.tmp
  • 两种方案都原生支持 .env 文件中 # 开头的注释,不需要额外处理。

内容的提问来源于stack exchange,提问作者Sam Jarman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 02:54:04