Makefile - ошибка «Нет такого файла или каталога»

Makefile - ошибка «Нет такого файла или каталога»

Я пытаюсь создать цель Makefile, которая сначала проверяет, существует ли мой контейнер Docker. Если он существует, то я хочу выполнить команду Docker Container Restart, в противном случае я хочу выполнить команду Docker Run, чтобы создать и запустить контейнер.

Я закодировал ниже, но получаю ошибку, показанную ниже. Результат = 1 верен, так как у меня запущен контейнер. Я удалил контейнер и проверил, что результат становится 0, что также верно. Проблема, похоже, возникает, когда я пытаюсь использовать result в операторе 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

Вместо реализации смеси кода скрипта оболочки и переменных make я предлагаю реализовать это как чистый скрипт оболочки, интегрированный в 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)

Связанный контент