不能在Makefile上用if egrep转换bash脚本



我想转换并执行

if egrep -r 'my_pattern' ./template_builder
then exit 1
elif egrep -r 'my_second_pattern' ./template_builder
then exit 1
fi

在Makefile中,目前还没有成功。

创建这个:

cd /tmp;
mkdir template_builder;
echo "not_pattern" >> ./template_builder/test.txt
# Do the command at the top, nothing happens
echo "my_pattern" >> ./template_builder/test.txt
# Do the command at the top, terminal stops
touch Makefile 

在Makefile中,我认为这会起作用:

check:
if egrep -r 'my_pattern' ./template_builder
then exit 1
elif egrep -r 'my_second_pattern' ./template_builder
then exit 1
fi
make check
if egrep -r 'my_pattern' ./template_builder
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [template] Error 2

我该如何解决这个问题?

你的尝试离成功不远了!

在每行末尾添加反斜杠,并将;s作为显式命令分隔符(当然要使用真正的制表符而不是下面的8个空格缩进):

check:
if egrep -r 'my_pattern' ./template_builder; 
then exit 1; 
elif egrep -r 'my_second_pattern' ./template_builder; 
then exit 1; 
fi

如果我理解正确,如果位于/tmp的目录template_builder不包含与字符串'my_pattern''my_second_pattern'匹配的文件,则您希望以错误码退出make

你可以在Makefile中使用这个规则来实现:

check:
egrep -r -v 'my_pattern' /tmp/template_builder || egrep -r -v 'my_second_pattern' /tmp/template_builder

解释:第一个egrep在找到匹配的情况下将返回一个错误。由于||操作符的存在,第二个egrep将被调用。第二个命令的结果将是make将看到的结果。如果它返回一个错误,make的执行被中止,这似乎是你所期望的行为。

注意:我编辑了我的答案。右布尔运算符是||而不是&&

正如其他人已经注意到的,make在一个新的shell子进程中运行配方中的每个单独的行。(需要说明的是,它使用的是开箱即用的sh,而不是Bash。)一个简单的修复是在每行的末尾添加一个反斜杠来转义换行符,这些换行符应该在与下一行相同的shell中执行。(您还需要在某些地方添加分号,例如在thenelsefi之前。)但是您确实需要重构以使用make的功能和习惯用法。

make的默认逻辑是,如果任何一行失败,将终止配方。因此,您的代码可以简化为简单的

check: template_builder
! egrep -r 'my_pattern' $<
! egrep -r 'my_second_pattern' $<

显式的exit 1在这里是不必要的(否定零退出代码会产生这样的结果);但是如果你想强制一个特定的退出码,你可以用

egrep -r 'my_pattern' $< && exit 123 || true

现代POSIX更喜欢grep -E而不是传统的egrep;当然,对于这些简单的模式,您可以只使用grep,甚至grep -F(nfgrep

)。此外,如果您想在同一组文件中搜索这两种模式,那么同时搜索它们会更有效。

check: template_builder
! egrep -e 'my_pattern' -e 'my_second_pattern' -r $<

…或者将它们组合成一个正则表达式my_(second_)?pattern(需要egrep/grep -E)。

还请注意我是如何将依赖项分解到$<中并使其显式的;但是你可能想让这个食谱.PHONY,这样即使没有任何改变,它也会被执行。

(你不能直接复制/粘贴这段代码,因为Stack Overflow会愚蠢地将markdown源代码中的制表符呈现为空格。)

最新更新