如何在Makefile中使用heredoc?现有示例Makefile无法运行
在Makefile中正确使用Heredoc的方法
你的这份Makefile出问题主要是因为heredoc的语法和Makefile的命令执行规则没匹配上——Make默认会把每个缩进的命令行当成单独的shell进程来执行,而heredoc需要在同一个shell会话里完整传递给docker build,另外你加的反斜杠也打乱了shell的语法解析。
下面给你两种可行的修复方案,按需选择:
方案一:基础写法(无缩进,最稳妥)
直接把docker build命令和heredoc内容放在同一个shell执行块里,注意heredoc的结束标记EOF必须顶格写,不能有任何缩进:
EXECUTABLE=server build: docker build -t $(EXECUTABLE) - <<EOF FROM scratch ADD bin/$(EXECUTABLE) /bin/$(EXECUTABLE) CMD ["/bin/$(EXECUTABLE)"] EOF
关键要点:
- 命令行(包括
docker build那一行)前面必须用制表符缩进(Makefile要求命令行必须用制表符,除非你用.RECIPEPREFIX修改); - Make会先展开
$(EXECUTABLE)变量,再把完整的heredoc内容传给docker build处理; EOF顶格是shell的要求,否则shell会认为这只是heredoc的一部分,一直等待结束标记。
方案二:带缩进的整洁写法
如果你想让heredoc内容有缩进(代码更易读),可以用<<-EOF代替<<EOF,这样shell会忽略结束标记和heredoc内容前面的制表符(注意只能是制表符,不能是空格):
EXECUTABLE=server build: docker build -t $(EXECUTABLE) - <<-EOF FROM scratch ADD bin/$(EXECUTABLE) /bin/$(EXECUTABLE) CMD ["/bin/$(EXECUTABLE)"] EOF
关键要点:
- 这里的缩进必须是制表符,空格的话shell不会识别,会导致dockerfile内容带空格缩进,从而报错;
<<-的作用就是去掉heredoc内容前的制表符,最终传给docker build的dockerfile内容还是无缩进的正确格式。
为什么你的原写法会失败?
你原代码里每行末尾加的反斜杠会让Make把这些行拼接成一个长命令,但反斜杠后面的空格会导致shell解析出错;另外,即使去掉空格,Make的命令行拆分规则也会让heredoc内容被当成单独的命令执行,根本不会传给docker build,自然无法正常运行。
内容的提问来源于stack exchange,提问作者user8725011
相关产品推荐
相关产品推荐

