Dockerコンテナが存在するかどうかを最初に確認するMakefileターゲットを作成しようとしています。存在する場合はDockerコンテナの再起動コマンドを実行し、それ以外の場合はDocker Runコマンドを実行してコンテナを作成して起動しようとします。
以下のコードを書きましたが、以下のエラーが発生します。コンテナが実行中なので、結果 = 1 が正しい。コンテナを削除し、結果がゼロになるかどうかをテストしましたが、これも正しいです。問題は、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)