Makefile shell调用中的哈希导致意外行为

Ant*_*ony 8 shell makefile g++ echo

以下命令根据g ++认为的位置打印特定C++标头的绝对路径.

echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-:  //' -e 's/ \\//'
Run Code Online (Sandbox Code Playgroud)

在我的系统上,这输出: /usr/local/include/ham/hamsterdb.hpp

尝试在Makefile中运行它以设置变量时遇到问题:

FILE=$(shell echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-:  //' -e 's/ \\//')

.PHONY spec

spec:
    @echo $(FILE)
Run Code Online (Sandbox Code Playgroud)

这会输出一个新行.我认为这是混乱make的哈希('#')字符; 如果我重写这样的FILE=...行:

FILE=$(shell echo \#include\<ham/hamsterdb.h\>)
Run Code Online (Sandbox Code Playgroud)

输出仍然没有.

Eld*_*mov 11

您必须两次转义哈希才能在函数内使用它:一次用于Make,另一次用于shell.

那是,

FILE = $(shell echo \\\#include\ \<ham/hamsterdb.h\>)
Run Code Online (Sandbox Code Playgroud)

注意三个反斜杠,而不是人们所期望的两个反斜杠.需要第三个反斜杠,否则第一个反斜杠将逃脱第二个反射,哈希仍然没有转义.

UPD.

另一种可能的解决方案是仅转义Make的哈希并使用Bash单引号来防止将哈希解释为shell注释.这也消除了逃避空间的需要,<并且>:

FILE = $(shell echo '\#include <ham/hamsterdb.h>')
Run Code Online (Sandbox Code Playgroud)