无法在 Makefile 上使用 if egrep 转换 bash 脚本
Cannot convert bash script with if egrep on Makefile
我要转换执行
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
我该如何解决这个问题?
如果我没理解错的话,如果位于/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
会 return 一个错误,如果他找到一个匹配。由于 ||
运算符的存在,第二个 egrep
将被调用。第二个命令的结果将是 make
将看到的结果。如果它 return 是一个错误,make
的执行将被中止,这似乎是您所期望的行为。
注意:我编辑了我的答案。正确的布尔运算符是 ||
而不是 &&
.
您的尝试离成功不远了!
在每一行的末尾添加反斜杠,并且 ;
s 作为明确的命令分隔符(当然使用真正的制表符而不是下面的 8-space 缩进):
check:
if egrep -r 'my_pattern' ./template_builder; \
then exit 1; \
elif egrep -r 'my_second_pattern' ./template_builder; \
then exit 1; \
fi
正如其他人已经指出的那样,make
在新的 shell 子流程中运行配方中的每一行。 (为了记录,它使用开箱即用的 sh
,而不是 Bash。)简单的修复是添加一个反斜杠以转义每行末尾的换行符,这应该在同一行执行shell 作为下一个。 (你还需要在某些地方添加分号,比如在 then
和 else
和 fi
之前。)但是你真的想重构使用 [=13 的设施和习语=].
make
的默认逻辑是在任何一行失败时终止配方。因此,您的代码可以简化为
check: template_builder
! egrep -r 'my_pattern' $<
! egrep -r 'my_second_pattern' $<
这里不需要明确的 exit 1
(否定零退出代码会产生这样的结果);但是如果你想强制执行一个特定的退出代码,你可以用
egrep -r 'my_pattern' $< && exit 123 || true
现代 POSIX 比传统 egrep
更喜欢 grep -E
;当然,对于这些简单的模式,您可以只使用 grep
,甚至 grep -F
(née fgrep
).
此外,如果您想在同一组文件中搜索这两种模式,一次搜索它们会更有效率。
check: template_builder
! egrep -e 'my_pattern' -e 'my_second_pattern' -r $<
... 或将它们组合成一个正则表达式 my_(second_)?pattern
(需要 egrep
/ grep -E
)。
另请注意我是如何将依赖关系分解为 $<
并使其明确的;但是你可能想要制作这个食谱 .PHONY
,这样即使没有任何改变它也会被执行。
(你不能直接 copy/paste 这段代码,因为 Stack Overflow 愚蠢地将 markdown 源中的文字标签呈现为空格。)
我要转换执行
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
我该如何解决这个问题?
如果我没理解错的话,如果位于/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
会 return 一个错误,如果他找到一个匹配。由于 ||
运算符的存在,第二个 egrep
将被调用。第二个命令的结果将是 make
将看到的结果。如果它 return 是一个错误,make
的执行将被中止,这似乎是您所期望的行为。
注意:我编辑了我的答案。正确的布尔运算符是 ||
而不是 &&
.
您的尝试离成功不远了!
在每一行的末尾添加反斜杠,并且 ;
s 作为明确的命令分隔符(当然使用真正的制表符而不是下面的 8-space 缩进):
check:
if egrep -r 'my_pattern' ./template_builder; \
then exit 1; \
elif egrep -r 'my_second_pattern' ./template_builder; \
then exit 1; \
fi
正如其他人已经指出的那样,make
在新的 shell 子流程中运行配方中的每一行。 (为了记录,它使用开箱即用的 sh
,而不是 Bash。)简单的修复是添加一个反斜杠以转义每行末尾的换行符,这应该在同一行执行shell 作为下一个。 (你还需要在某些地方添加分号,比如在 then
和 else
和 fi
之前。)但是你真的想重构使用 [=13 的设施和习语=].
make
的默认逻辑是在任何一行失败时终止配方。因此,您的代码可以简化为
check: template_builder
! egrep -r 'my_pattern' $<
! egrep -r 'my_second_pattern' $<
这里不需要明确的 exit 1
(否定零退出代码会产生这样的结果);但是如果你想强制执行一个特定的退出代码,你可以用
egrep -r 'my_pattern' $< && exit 123 || true
现代 POSIX 比传统 egrep
更喜欢 grep -E
;当然,对于这些简单的模式,您可以只使用 grep
,甚至 grep -F
(née fgrep
).
此外,如果您想在同一组文件中搜索这两种模式,一次搜索它们会更有效率。
check: template_builder
! egrep -e 'my_pattern' -e 'my_second_pattern' -r $<
... 或将它们组合成一个正则表达式 my_(second_)?pattern
(需要 egrep
/ grep -E
)。
另请注意我是如何将依赖关系分解为 $<
并使其明确的;但是你可能想要制作这个食谱 .PHONY
,这样即使没有任何改变它也会被执行。
(你不能直接 copy/paste 这段代码,因为 Stack Overflow 愚蠢地将 markdown 源中的文字标签呈现为空格。)