0

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

4

2 回答 2

1

如果您编写如下规则,它应该会产生您想要的结果:

target:
    @echo $(shell find . | grep -E '\.c$$|\.h$$|\.cpp$$|\.hpp$$|Makefile' | xargs cat | wc -l)
于 2012-08-02T21:22:04.970 回答
0

在 Makefiles 中,$ 用于 make 变量,例如 $(HEADERS),其中 HEADERS 之前使用 = 定义。

要在内联 bash 中使用 $,您必须将它们加倍以转义它们。$$VAR 将引用一个 shell 变量,而 .c$$ 等应该为您正在使用的正则表达式转义 $。

以下内容应该足以逃避 $'s 你想要完成的事情

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

另外,请注意,您可以并且经常会看到用于此目的的 SubShell。这些是用 () 创建的。这将使内壳定义的任何变量都成为该壳及其命令组的本地变量。

于 2014-08-31T15:11:40.443 回答