为何rm命令在Shell中正常运行但在Makefile中失效?
Makefile中rm大括号扩展失效的解决办法
问题原因
GNU Make默认使用/bin/sh作为执行命令的shell(Ubuntu 22.04中/bin/sh指向dash),而你用的paper.{abs,blg,...}这种大括号扩展是Bash的专属特性,dash不支持该语法,因此Make执行时不会展开括号内的后缀列表,直接把整个paper.{abs,blg,pdf,aux,log,bbl,out,xmpdata}当作单个文件名,自然找不到对应文件报错。
解决办法
方法1:指定Make使用Bash执行命令
在Makefile的最开头添加一行:
SHELL := /bin/bash
这样Make后续执行所有命令都会调用Bash,大括号扩展就能正常解析,原rm命令无需修改即可工作。
方法2:直接枚举所有目标文件
如果不想依赖Bash特性,可以直接把要删除的文件全列出来:
clean: rm paper.abs paper.blg paper.pdf paper.aux paper.log paper.bbl paper.out paper.xmpdata
方法3:使用Make的wildcard函数提前匹配
利用Make内置的wildcard函数先匹配存在的文件,再传给rm命令(即使部分文件不存在也不会报错):
clean: rm $(wildcard paper.{abs,blg,pdf,aux,log,bbl,out,xmpdata})
注意事项
不要给大括号表达式加单引号或双引号,引号会强制shell把整个表达式当作单个字符串,彻底阻止扩展,这也是你之前加引号无效的原因。
内容的提问来源于stack exchange,提问作者Gergely
相关产品推荐
相关产品推荐

