我正在尝试创建一个 Makefile 目标,它首先检查我的 Docker 容器是否存在。如果存在,那么我想发出 Docker 容器重新启动命令,否则我想发出 Docker Run 命令来创建并启动容器。
我已经编写了下面的代码,但收到了如下所示的错误。结果 = 1 是正确的,因为我确实有一个容器正在运行。我已经移除了容器并测试结果变为0,这也是正确的。问题似乎是当我尝试在ifeq
语句中使用结果时。有人可以告诉我我做错了什么吗? (我在调试时暂时注释掉了 docker 命令并用 echo true / false 替换了它们)。
start_docker_myapp:
result = $(shell (docker ps -a | grep myapp ) | wc -l )
ifeq (${result}, 1)
@echo 'true'
# docker restart ${IMAGE}
else
@echo 'false'
# docker run -v ${DIR}/var/log/docker:/var/log/myapp -p 1812:1812/udp -p 1813:1813/udp --detach --name ${IMAGE} $(REGISTRY)/$(IMAGE):$(TAG)
endif
终端输出
$ make start_docker_myapp result = 1 make: result: No such file or directory make: *** [start_docker_myapp] Error 1 $
答案1
您的 Makefile 存在许多问题(除了 Makefile 是否是适当的解决方案的问题之外):
- 条件指令不是配方的一部分,因此它们不能以制表符开头;
- 条件指令在读取 Makefile 时进行评估,因此必须事先分配变量并且不能是特定于目标的;
docker ps -a
返回所有已知容器的信息,包括非运行容器;- 虚假目标应如此声明。
以下作品:
result = $(shell docker ps -f name=myapp -q | wc -l)
start_docker_myapp:
ifeq ($(strip $(result)),1)
@echo true
else
@echo false
endif
.PHONY: start_docker_myapp
答案2
要在目标内设置变量值,必须使用以下eval
语法:
start_docker_myapp:
$(eval result = $(shell (docker ps -a | grep myapp ) | wc -l ))
@echo "result is " result
endif
或者,您可以在规则之外评估此变量:
result = $(shell (docker ps -a | grep myapp ) | wc -l )
start_docker_myapp:
@echo "result is " result
endif
答案3
我建议将其实现为集成在Makefile
.
您可以简单地检查的退出代码,而不是检查 的输出grep
并wc
比较数字。grep
# don't forget to declare start_docker_myapp as a phony target
.PHONY: start_docker_myapp
# Assuming you intended to use Make variables everywhere, I changed all ${VAR} to $(VAR).
# If your grep supports option -q you can use this instead of redirection to /dev/null.
start_docker_myapp:
if docker ps -a | grep myapp >/dev/null; \
then \
echo 'true'; \
# docker restart $(IMAGE); \
else \
echo 'false'; \
# docker run -v $(DIR)/var/log/docker:/var/log/myapp -p 1812:1812/udp -p 1813:1813/udp --detach --name $(IMAGE) $(REGISTRY)/$(IMAGE):$(TAG); \
fi
或者用布尔运算符代替if...then...
.PHONY: start_docker_myapp
start_docker_myapp:
docker ps -a | grep myapp >/dev/null && docker restart $(IMAGE) || docker run -v $(DIR)/var/log/docker:/var/log/myapp -p 1812:1812/udp -p 1813:1813/udp --detach --name $(IMAGE) $(REGISTRY)/$(IMAGE):$(TAG)