Makefile - shell命令没有考虑“$”

时间:2012-07-19 11:55:17

标签: bash makefile grep

我有一个具有以下规则的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无法正确运行我的脚本?

2 个答案:

答案 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及其命令组本地定义。