我有以下makefile
.ONESHELL:
p3:
@VAR1=$(shell cat meow) # first file
@echo "$${VAR1}"
@VAR2=$(shell grep -oP "name:\s*\K.+" file2)
@echo "$${VAR2}"
# @VAR3=$(shell grep -oP "name:\s*\K.+" $${VAR1})
# @echo "$${VAR3}"
和
echo -e "file2" > meow
echo -e "name: My_Name" > file2
当我运行
make p3
时,我看到:
$ make p3
file2
My_Name
太棒了。然而,我真正想要的不是在 makefile 中硬编码“file2”,而是从“喵”文件的内容中接收它。
当我取消注释
$${VAR1}
的调用时,程序无限期挂起。逃避该变量的方法似乎也不起作用,$VAR1
,$$VAR1
,$(VAR1)
,$$(VAR1)
,${VAR1}
,$${VAR1}
都失败了。
如何从使用 make 变量的 shell 函数中获取返回值?如果这需要
define
我也愿意。
make recipes是shell脚本,在make recipe中使用
shell
函数总是错误的。行为是不一样的,因为 make 在将配方传递给 shell 之前扩展它们,而不是在 shell 执行它们的过程中。不要写:
VAR2=$(shell grep -oP "name:\s*\K.+" file2)
写:
VAR2=`grep -oP "name:\s*\K.+" file2`
或:
VAR2=$$(grep -oP "name:\s*\K.+" file2)
(需要双
$$
来逃避 make 在将它们传递给 shell 之前对食谱的扩展)。
最好不要使用
@
使您的食谱静音,尤其是在调试 Makefile 时。更喜欢等效的 make 选项或特殊目标(-s
和 .SILENT
与 GNU make)。
您可能应该引用您的 shell 扩展(例如,
$${VAR1}
中的grep -oP "name:\s*\K.+" $$VAR1)
。
所以,对于您的 Makefile,您可以尝试以下操作:
.ONESHELL:
# Uncomment the following line when done
#.SILENT:
p3:
VAR1=`cat meow`
echo "$${VAR1}"
VAR2=`grep -oP "name:\s*\K.+" file2`
echo "$${VAR2}"
VAR3=`grep -oP "name:\s*\K.+" "$${VAR1}"`
echo "$${VAR3}"