我正在使用一个将由Makefile使用的bash脚本动态生成config.mk
。该文件由:
cat > config.mk <<CFG
SOMEVAR := $value_from_bash1
ANOTHER := $value_from_bash2
CFG
如何确保生成的文件确实包含$value_from_bash*
的内容,而不是扩展/解释的内容?我可能需要将$
转移到$$
和\
转移到\\
,但还有其他字符需要转义吗?也许有一个我没有听说过的特殊文字作业?
空间似乎也很麻烦:
$ ls -1
a b
a
$ cat Makefile
f := a b
default_target:
echo "$(firstword $(wildcard ${f}))"
$ make
a
如果我使用f := a\ b
它有效(使用f := 'a b'
之类的引号也不起作用,makefile只会将其视为常规字符)
答案 0 :(得分:52)
好的,事实证明,Makefile几乎不需要自行转义,但shell解释器执行的命令需要进行转义。
在Makefile中具有特殊含义且需要转义的字符是:
#
,comment)变为\#
$
,变量开头)变为$$
新行不能插入变量中,但为了避免破坏Makefile的其余部分,请在前面加上反斜杠,以便忽略换行符。
太糟糕了,反斜杠本身无法转义(\\
仍然是\\
而不是\
,如您所料。这使得无法在字符串的末尾放置文字斜杠,因为它将使用换行符或后续注释的散列值。一个空格可以放在行的末尾,但也可以放在变量本身。
配方本身被解释为一个shell命令,没有任何花哨的转义,所以你要自己逃避数据,只要想象你正在编写一个shellcript并从其他文件中插入变量。这里的策略是将变量放在单引号之间,只用'
转义'\''
(关闭字符串,插入文字'
并开始一个新字符串)。示例:mornin' all
变为'morning'\'' all'
,相当于"morning' all"
。
第一个字+通配符问题是由于firstword
将带有空格的文件名视为单独的文件名。此外,wildcard
使用\
展开转义,因此x\ y
匹配为一个单词x y
,而不是两个单词。
答案 1 :(得分:5)
似乎完整这个问题的答案是在互联网上无处,所以我终于坐下来想出了Windows案例。
具体来说,“Windows案例”是指在Windows中有效的文件名,这意味着它们不包含字符\
,/
,{{1 },*
,?
,"
,^
,<
,>
或换行符。这也意味着|
和\
都被认为是有效的目录分隔符,用于Make。
一个例子将比我能解释的更清楚。基本上,如果您尝试匹配此文件路径:
/
然后你必须写下这些规则:
Child\a$b {'}(a.o#$@,&+=~`),[].c
长时间盯着它,它会开始有点遥感。
这适用于我的MSYS2环境,因此我认为它是正确的。
答案 2 :(得分:2)