Bash 如何在Makefile中为until循环编写超时函数
我有下面的MakefileBash 如何在Makefile中为until循环编写超时函数,bash,makefile,Bash,Makefile,我有下面的Makefile ready: until docker-compose logs some_svc | grep "ready"; do echo -n .; sleep 1; done 我想用一个超时函数来包装它 define check_timeout timer=0 $(1); do ((timer++)); if [[ "$$timer" == 60 ]]; then
ready:
until docker-compose logs some_svc | grep "ready"; do echo -n .; sleep 1; done
我想用一个超时函数来包装它
define check_timeout
timer=0
$(1); do
((timer++));
if [[ "$$timer" == 60 ]]; then
exit -1
fi
sleep 1
done
endef
ready:
$(call check_timeout, until docker-compose logs some_svc | grep "ready")
但我得到了以下错误:
$ make ready
timer=0
until docker-compose logs some_svc | grep "ready."; do
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [ready] Error 2
有什么想法吗?在你的职业生涯中,你会遇到无数关于makefile的问题。许多问题可以通过问自己以下问题来解决: 这是否需要放在Makefile中,或者将此功能放在bash脚本中并从Makefile简单调用该脚本会更容易 为了提高Makefile的可读性并简化您的生活,将此功能放入bash脚本并从Makefile调用它 生成文件 在Makefile中,我们使用
timeout
命令对要调用的脚本设置时间限制。我们还通过使用in-case-of-error|
操作符来处理错误
ready:
timeout 60 bash until_docker.sh || exit -1
直到docker.sh
在bash脚本中,我们实现了希望调用的功能
直到docker compose记录一些| svc | grep“就绪”;做回显。;睡眠1;
您有一些问题
第一个是make总是使用/bin/sh
来运行菜谱。无论您的个人交互式shell是bash、zsh还是csh,它都将始终使用/bin/sh
。在许多系统上,/bin/sh
不是bash,而是一个基本的POSIX shell,如dash
。脚本中的许多元素都不是有效的POSIX shell脚本。因此,如果您想要完全可移植(例如,到基于Debian/Ubuntu的系统),就不能在makefile中依赖这些bash ISM
或者,您必须明确告诉make您想要bash,包括:
SHELL := /bin/bash
当然,这在任何根本没有安装bash的系统上都会失败
其次,如果希望配方位于单个逻辑行上并传递给单个shell调用,那么将脚本放入define
块并不能免除使用反斜杠的需要。命令之间需要分号(如exit-1
和fi
等),行的末尾需要反斜杠
这应该起作用:
define check_timeout
timer=0; \
$(1); do \
timer=$$(expr $$timer + 1); \
if [ "$$timer" = 60 ]; then \
exit -1; \
fi; \
sleep 1; \
done
endef
ready:
$(call check_timeout, until echo ready | grep "ready")
这与其说是回答,不如说是评论。