在Makefile中echo输出JSON格式环境变量报错如何处理?
报错原因
- Make 执行规则内的Shell命令时,会先对内置变量做预展开处理,再将展开后的内容逐行传递给
/bin/bash执行。 - 初始导出的带换行JSON变量
${JSON}被预展开后,原本的@echo ${JSON}会被拆分为多行命令:@echo { "key":"val" } - 第一行
echo后没有闭合的引号标识,Shell执行到行尾时判定命令不完整,直接抛出语法错误。 - 后续修改为单行JSON且新增单引号包裹
${JSON}后,展开后的命令为完整的@echo '{ "key":"val" }',单引号完全闭合因此可以正常执行,但如果JSON内容本身包含单引号,仍然会触发语法异常。
更规范的实现方案
方案1:转义变量让Shell层直接读取环境变量(最推荐)
用$$转义变量名,阻止Make层预展开变量,直接把命令交给Shell读取环境变量值,兼容任意格式的JSON内容,不需要修改环境变量的导出方式:
.PHONY: test test: @echo "$$JSON"
该方案下JSON带换行、含特殊字符(单引号、双引号、反斜杠等)都不会触发语法问题。
方案2:Makefile内部定义多行JSON变量
如果JSON不需要从外部环境传入,直接在Makefile内用define定义多行变量即可:
define JSON { "key":"val" } endef export JSON # 需要传递给子进程的话要加export .PHONY: test test: @echo "$$JSON"
方案3:Make层保留原始变量值
如果确实需要在Make层展开变量,用$(value)函数保留变量的原始换行格式:
.PHONY: test test: @echo '$(value JSON)'
内容的提问来源于stack exchange,提问作者mrfr
相关产品推荐
相关产品推荐

