Makefile执行shell命令输出丢失换行符问题排查
问题根因
格式丢失是错误使用Make的$(shell)函数导致的:
$(shell <command>)是Make的内置求值函数,执行逻辑是先运行传入的命令,再把命令输出中的所有换行符全部替换为空格,最终返回拼接好的单行字符串给Make解析,设计目的是捕获命令输出赋值给变量,不是用来直接向终端打印执行结果。- Make目标下带缩进的命令段(recipe)本身就会被直接递交给系统shell执行,命令输出会原样透传到终端,不需要额外套
$(shell)包裹。
你观察到的段落拼接、空行消失的现象,完全匹配$(shell)的默认处理逻辑:原terraform输出里的单换行、分隔段落的连续换行全被替换成空格,最终就成了所有内容挤在一起的效果。
修复方案
方案1:移除多余的$(shell)包裹(推荐,适配当前场景)
直接在目标下写脚本调用即可,注意命令行前的缩进必须使用Tab字符,不能用空格,否则Make会报语法错误:
plan: ./runcommands.sh init
修改后执行make plan,脚本输出会直接透传到终端,和你手动在控制台执行脚本的效果完全一致,换行、空行、terraform自带的输出格式都会完整保留。
方案2:需捕获输出为变量时的格式保留写法
如果后续有需求要把脚本执行结果存为Make变量做二次处理,需要提前定义换行符变量,避免Make自动替换换行:
# 定义换行变量,define和endef之间必须保留两个空行 define NEWLINE endef plan: $(eval TF_RESULT := $(shell ./runcommands.sh init)) # 输出时恢复原有换行格式 $(info $(subst $(NEWLINE),$(NEWLINE),$(TF_RESULT)))
该写法仅适合需要对输出做后续加工的场景,如果只是执行脚本查看结果,直接用方案1即可,没有额外复杂度。
内容的提问来源于stack exchange,提问作者emboole
相关产品推荐
相关产品推荐

