Makefile: no existe tal error de archivo o directorio

Makefile: no existe tal error de archivo o directorio

Estoy intentando crear un destino Makefile que primero verifica si mi contenedor Docker existe. Si existe, quiero emitir el comando Docker Container Restart; de lo contrario, quiero emitir el comando Docker Run para crear e iniciar el contenedor.

He codificado lo siguiente pero aparece el error que se muestra a continuación. El resultado = 1 es correcto ya que tengo un contenedor en ejecución. Quité el contenedor y probé que el resultado se convierte en 0, lo cual también es correcto. El problema parece surgir cuando intento utilizar el resultado en la ifeqdeclaración. ¿Alguien puede aconsejarme qué estoy haciendo mal? (Comenté temporalmente los comandos de la ventana acoplable y los reemplacé con echo true/false justo mientras estoy depurando).

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

Salida desde la terminal

$ make start_docker_myapp
result =        1
make: result: No such file or directory
make: *** [start_docker_myapp] Error 1
$

Respuesta1

Hay una serie de problemas con su Makefile (más allá de la cuestión de si un Makefile es la solución adecuada):

  • las directivas condicionales no son parte de una receta, por lo que no deben comenzar con una pestaña;
  • las directivas condicionales se evalúan a medida que se lee el Makefile, por lo que las variables deben asignarse previamente y no pueden ser específicas de un objetivo;
  • docker ps -adevuelve información sobre todos los contenedores conocidos, incluidos los contenedores que no están en funcionamiento;
  • Los objetivos falsos deben declararse como tales.

Las siguientes obras:

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

Respuesta2

Para establecer un valor de variable dentro de un objetivo, debe usar la evalsintaxis:

start_docker_myapp:
    $(eval result = $(shell (docker ps -a | grep myapp ) | wc -l ))
    @echo "result is " result
    endif

Alternativamente, puedes evaluar esta variable fuera de una regla:

result = $(shell (docker ps -a | grep myapp ) | wc -l )

start_docker_myapp:        
    @echo "result is " result
    endif

Respuesta3

En lugar de implementar una combinación de código de script de shell y crear variables, sugiero implementar esto como un script de shell puro integrado en el archivo Makefile.

En lugar de verificar la salida de grepwith wcy comparar el número, simplemente puede verificar grepel código de salida de .

# 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

O con operadores booleanos en lugar deif...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)

información relacionada