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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:13:07