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

Makefile执行apply目标时读取terraform输出的变量echo为空如何解决

Makefile执行terraform后变量为空问题解决方案

根因

  • Make默认会为目标下的每一行命令启动独立的子shell执行,前一行子shell内赋值的变量无法传递到后一行的子shell中,所以echo行读取不到前面的变量值。
  • 你当前使用的$(shell)是Make层面的内置函数,执行时机早于目标下所有命令的执行,会在terraform apply运行前就执行读取terraform输出的操作,若你是首次运行无历史状态文件,这一步直接会拿到空值,你当前能看到赋值日志只是因为本地已有之前生成的terraform状态缓存。

解决方案

两种方案可选:

方案1:命令连行执行(兼容性最好)

将变量赋值和后续所有需要用到变量的操作通过反斜杠连为同一行,让所有操作在同一个子shell内完成。同时将Make层面的$(shell)替换为shell层面的命令替换(用$$(...)转义,避免被Make提前解析),配合jq的-r参数去掉输出的引号:

apply: init
	@terraform apply -auto-approve
	@BUCKET=$$(terraform output -json | jq -r '.S3_Bucket.value') \
	&& DYNAMODB=$$(terraform output -json | jq -r '.dynamo_db_lock.value') \
	&& echo $$BUCKET \
	# 后续sed命令可直接在同一链路上调用
	&& sed -i "s/你的占位符/$$BUCKET/g" 目标文件路径

提示:Makefile中目标下的所有命令行必须用Tab缩进,不能用空格,否则会触发语法错误

方案2:启用ONESHELL(写法更简洁)

如果你使用的是GNU Make 3.82及以上版本,可以在Makefile开头声明.ONESHELL特殊目标,该目标下的所有命令会在同一个shell内执行,支持直接跨行调用变量:

# 放在Makefile最顶部
.ONESHELL:

apply: init
	@terraform apply -auto-approve
	BUCKET=$$(terraform output -json | jq -r '.S3_Bucket.value')
	DYNAMODB=$$(terraform output -json | jq -r '.dynamo_db_lock.value')
	@echo $$BUCKET
	# 后续sed命令直接调用即可
	sed -i "s/你的占位符/$$BUCKET/g" 目标文件路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:12:03