我想转换并执行
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中执行。(您还需要在某些地方添加分号,例如在then
和else
和fi
之前。)但是您确实需要重构以使用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源代码中的制表符呈现为空格。)