我有一个具有以下规则的Makefle
bash -c "find . |grep -E '\.c$|\.h$|\.cpp$|\.hpp$|Makefile' | xargs cat | wc -l"
我期望make运行引用的bash脚本并返回项目中的行数。
直接在终端中运行命令可以正常工作,但在makefile中不起作用。
如果我从脚本中删除$
,它确实有效......但不是预期的(因为我只想要*.{c,cpp,h,hpp,Makefile}
。
为什么bash -c
无法正确运行我的脚本?
答案 0 :(得分:1)
如果您编写如下规则,它应该产生您想要的结果:
target:
@echo $(shell find . | grep -E '\.c$$|\.h$$|\.cpp$$|\.hpp$$|Makefile' | xargs cat | wc -l)
答案 1 :(得分:0)
在Makefile中,$用于make变量,例如$(HEADERS),其中HEADERS之前已使用=定义。
要使用$ in inline bash,你必须将它们加倍才能逃脱它们。 $$ VAR将引用一个shell变量,而.c $$等等应该为您正在使用的正则表达式转义$。
以下内容应该足以逃避你想要实现的目标
bash -c "find . |grep -E '\.c$$|\.h$$|\.cpp$$|\.hpp$$|Makefile' | xargs cat | wc -l"
此外,如果添加此声明,则可以在Makefile中全局使用bash而不是默认的/ bin / sh:
SHELL = /bin/bash
通过上述内容,您应该能够使用find命令而无需bash -c和引号。如果SHELL定义如上,则以下内容应该有效:
find . |grep -E '\.c$$|\.h$$|\.cpp$$|\.hpp$$|Makefile' | xargs cat | wc -l
另外,请注意,您可以并且经常会看到用于此目的的SubShells。这些是用()创建的。这将使内壳的任何变量由该shell及其命令组本地定义。