
我正在嘗試建立一個 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)