Makefile执行clean目标时出现Shell语法错误求助
问题描述
在Ubuntu虚拟机中编写Makefile,希望实现clean功能删除除main.c、makefile、util.c、util.h外的所有文件,Makefile内容如下:
all: clean compile run compile: main.c util.c util.h @echo "-------------------------------------------" @echo "Compiling..." @gcc -o test main.c util.c run: @echo "-------------------------------------------" @echo "Running the tests...." @echo "================================================================> @./test @echo "================================================================> @echo "Completed tests...." clean: @echo "-------------------------------------------" @echo "Cleaning..." @rm -v !("main.c"||"makefile"||"util.c"||"util.h")
其他功能正常,但执行make clean时出现错误:
------------------------------------------- Cleaning... /bin/sh: 1: Syntax error: "(" unexpected make: *** [makefile:19: clean] Error 2
而rm -v !("main.c"||"makefile"||"util.c"||"util.h")直接在终端输入可正常运行,询问问题原因及解决方法。
原因分析
Make默认使用/bin/sh作为执行命令的shell,Ubuntu系统中/bin/sh是dash的软链接,你使用的!()属于Bash特有的**扩展通配符(extglob)**特性,dash不支持该语法,因此执行时触发语法错误。而终端默认使用Bash,所以命令能正常运行。
解决方法
方法1:指定Make使用Bash
在Makefile最开头添加一行,强制Make用Bash执行所有命令:
SHELL := /bin/bash
添加后原clean规则无需修改,即可正常执行。
方法2:使用兼容性更好的find命令
如果希望命令在任何POSIX兼容的shell中都能运行,可改用find命令替代extglob语法,修改clean规则为:
clean: @echo "-------------------------------------------" @echo "Cleaning..." @find . -maxdepth 1 -type f ! -name "main.c" ! -name "makefile" ! -name "util.c" ! -name "util.h" -exec rm -v {} +
参数说明:
-maxdepth 1:仅处理当前目录文件,不递归子目录-type f:仅匹配普通文件(若需要删除目录可去掉该参数)! -name "xxx":排除指定文件名-exec rm -v {} +:对找到的文件批量执行删除命令
额外提示
你的run规则中,echo命令存在引号未闭合的问题(如@echo "================================================================>),虽然当前未报错,但建议补全闭合引号,避免后续出现意外问题。
内容的提问来源于stack exchange,提问作者mishima2077
相关产品推荐
相关产品推荐

