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

在Makefile目标中加载生成的.env文件时为何出现permission denied?

Makefile加载.env文件触发Permission Denied的原因与解决办法

我需要在Makefile目标中重新加载环境文件,于是写了一个生成.env文件并尝试加载的示例,但运行时出现permission denied错误。已经给.env文件设置了chmod +r权限,问题还是没解决——文件能成功创建,但就是加载不了。

相关Makefile代码

ENV_FILE := .env

.PHONY: create-env-file
create-env-file:
    @echo "Generating environment file... $(ENV_FILE)"
    @echo "VAR1=1" > $(ENV_FILE)
    @echo "VAR2=2" >> $(ENV_FILE)

.PHONY: load-env-file
load-env-file:
    echo "- Reloading env file..."
    $(MAKE) create-env-file
    chmod +r $(ENV_FILE)
    include $(ENV_FILE)

.PHONY: start
start: load-env-file
    echo $(VAR2)

运行输出

$make start
echo "- Reloading env file..."
- Reloading env file...
/Library/Developer/CommandLineTools/usr/bin/make create-env-file
Generating environment file... .env
chmod +r .env
include .env
make: include: Permission denied
make: *** [load-env-file] Error 1

错误原因

核心问题是你在load-env-file目标的命令列表里写了include $(ENV_FILE),但**include是Makefile的内置指令,不是shell命令**。当Make执行目标里的命令时,会把每一行都当作shell命令去调用系统中的可执行程序,而你的系统中没有名为include的可执行文件,因此抛出了"Permission denied"的错误(这个报错有误导性,本质是找不到对应命令)。


解决方案

根据你需要使用变量的场景,分两种情况处理:

场景1:让Makefile本身访问.env中的变量

如果是想让Make的变量(比如$(VAR2))读取.env里的值,需要把include放在Makefile的全局范围,而非目标的命令中。若.env是动态生成的,可以用递归Make或生成后重新触发Make加载:

方案1:检查文件后全局包含

ENV_FILE := .env

.PHONY: create-env-file
create-env-file:
    @echo "Generating environment file... $(ENV_FILE)"
    @echo "VAR1=1" > $(ENV_FILE)
    @echo "VAR2=2" >> $(ENV_FILE)

# 若.env已存在则包含它
ifneq ($(wildcard $(ENV_FILE)),)
include $(ENV_FILE)
endif

.PHONY: start
start: create-env-file
    @$(MAKE) --no-print-directory print-var

.PHONY: print-var
print-var:
    echo $(VAR2)

方案2:递归调用Make加载变量

ENV_FILE := .env

.PHONY: create-env-file
create-env-file:
    @echo "Generating environment file... $(ENV_FILE)"
    @echo "VAR1=1" > $(ENV_FILE)
    @echo "VAR2=2" >> $(ENV_FILE)

.PHONY: start
start:
    $(MAKE) create-env-file
    $(MAKE) print-var

# 全局包含.env,递归调用时Make会加载已生成的文件
include $(ENV_FILE)
.PHONY: print-var
print-var:
    echo $(VAR2)

场景2:让shell命令访问.env中的变量

如果只是想在目标的shell命令中使用.env里的环境变量(比如echo $VAR2),可以用source(或.)命令加载.env,注意要在同一个shell进程中执行:

ENV_FILE := .env

.PHONY: create-env-file
create-env-file:
    @echo "Generating environment file... $(ENV_FILE)"
    @echo "VAR1=1" > $(ENV_FILE)
    @echo "VAR2=2" >> $(ENV_FILE)

.PHONY: load-env-file
load-env-file: create-env-file
    echo "- Reloading env file..."
    # 在同一shell中加载环境变量并执行命令
    . $(ENV_FILE) && echo $$VAR2

.PHONY: start
start: load-env-file
    # 若要在start的命令中使用,同样需要source
    . $(ENV_FILE) && echo $$VAR2

注意:这里用$$VAR2是因为Make会把单个$解析为Make变量,需要转义成$$让shell识别为shell变量。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:17:10