问题描述
mytarget:
@$(call my_func,echo \"hello world\")
define my_func
$(eval var := $(1))
if [[ "$(var)" != "" ]]; then \
$(var); \
fi;
endef
使用 make 命令执行时,会打印“hello world”(用双引号括起来) 我想要的只是在条件检查之前从 echo "hello world" 中删除 "。
我尝试使用以下语句但没有用:
var2 = $(echo $var | tr '"' '' 然后在 if 条件中使用 $(var2) 而不是 $(var) 它不工作。 任何帮助将不胜感激。
谢谢
解决方法
首先,您不应该将 @
添加到您的 makefile 配方中,直到它们 100% 工作。否则你会试图蒙住眼睛调试你的 makefile。
你的整个 makefile 脚本似乎可以写成:
mytarget:
$(call my_func,echo "hello world")
my_func = $1
并且它的工作方式完全相同:如果使用空参数调用 my_func
,则 $1
扩展为空字符串,这就是您无论如何要测试的内容。大概你有一些理由想要更复杂的配置,但正如我在评论中提到的,这似乎是一个 XY 问题。
我会给你一个简短的回答:make 不关心引用或反斜杠。您使用的任何引号或反斜杠都会逐字传递给 shell。因此,如果您将 echo \"foo\"
传递给 shell,它将打印引号。这完全符合预期。
如果您删除 @
,正如我上面提到的,事情对您来说会更清楚。
那么,为什么要添加反斜杠?看来您正在添加它们,否则条件 if [ "$1" != "" ]
将扩展为 if [ "echo "hello world"" != "" ]
,这是一个语法错误。
一个简单的解决方案是使用单引号而不是双引号:
mytarget:
$(call my_func,echo "hello world")
define my_func
if [ '$1' != '' ]; then \
$1; \
fi;
endef
当然,如果您使用包含单引号的值调用 my_func
,这将失败。
您有两种解决方案:
首先是使用 make 条件,而不是 shell 条件,因为 make 不关心引号等。这给了你:
mytarget:
$(call my_func,echo "hello world")
my_func = $(if $1,$1)
但这与我的第一个建议相同,只是单独使用 $1
。
如果您真的必须在 shell 中执行此操作,那么您必须为 shell 引用一些内容。 Make 的 subst
函数可以为您做到这一点:
mytarget:
$(call my_func,echo "hello world")
define my_func
if [ '$(subst ','\'',$1)' != '' ]; then \
$1; \
fi;
endef
用 '
替换 '\''
的所有实例。