在m4中,如何包含名称中包含环境变量的文件?
我想在m4文本中包含一个基于沙盒基目录的文件,而不使用在m4中,如何包含名称中包含环境变量的文件?,m4,M4,我想在m4文本中包含一个基于沙盒基目录的文件,而不使用-I开关 到目前为止,我已经了解了如何使用sys调用获取环境变量: define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')')dnl 接下来,我想包含一个基于该环境变量的文件: include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4) 我总共有: define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')') MODEL_
-I
开关
到目前为止,我已经了解了如何使用sys调用获取环境变量:
define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')')dnl
接下来,我想包含一个基于该环境变量的文件:
include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)
我总共有:
define(MODEL_ROOT,`syscmd(`printf $MODEL_ROOT')')
MODEL_ROOT
MODEL_ROOT/sw/lib/m4_macros/foreach2.m4
include(MODEL_ROOT/sw/lib/m4_macros/foreach2.m4)
其中打印:
/home/ross/sandbox
/home/ross/sandbox/sw/lib/m4_macros/foreach2.m4
/home/ross/sandboxforeach_example.m4:7: m4: Cannot open /sw/lib/m4_macros/foreach2.m4: No such file or directory
我知道includes的正常语法是
include(`file.m4')
但是如果我引用MODEL\u ROOT/sw/lib/m4\u macros/foreach2.m4
,那么m4就像:
[...]
include(`MODEL_ROOT/sw/lib/m4_macros/foreach2.m4')
m4投诉:
[...]
foreach_example.m4:7: m4: Cannot open MODEL_ROOT/sw/lib/m4_macros/foreach2.m4: No such file or directory
如何包含路径中包含环境变量的文件?我认为您需要使用
esyscmd
而不是syscmd
esyscmd
读取命令行输出。如其他答案所述,您必须使用GNU扩展名esyscmd
才能检索命令的输出。syscmd
宏直接打印到stdout,忽略所有宏和divert
s
这就是为什么它看起来像是MODEL_ROOT
在其他任何地方都可以工作:它确实可以,但只在m4不需要处理其输出的非常简单的情况下工作
然而,关于引用:
包括(MODEL\u ROOT/sw/lib/m4\u macros/foreach2.m4)
include(`MODEL\u ROOT/sw/lib/m4\u macros/foreach2.m4')
include(MODEL_ROOT`/sw/lib/m4_macros/foreach2.m4')
引号防止扩展MODEL\u ROOT
宏,因此不能将其括在此处(您希望将其展开的位置)。引用字符串的其余部分是“合适的”,因为您不希望用宏来扩展它
另一方面,从shell获取环境变量的更健壮的方法如下:
define(`HOME', esyscmd(`printf \`\`%s\'\' "$HOME"'))
这将避免由宏名称、百分号、反斜杠、全局字符或环境变量值中的空格引起的问题。此解决方案与您的解决方案之间的唯一区别是在变量周围添加了\``s\\'
和引号
需要注意的是:
esyscmd
总是将其输出扩展为宏,因此很难对其进行真正的消毒。尽管我在上面使用了引号符号,但如果环境变量中存在这些引号符号,它仍然会出错。您确实就是那个人。成功了。谢谢奇怪的是,除了在include
宏调用中,我实际上可以使用MODEL\u ROOT
。无论如何,谢谢!