Makefile – Fehler „Keine solche Datei oder kein solches Verzeichnis vorhanden“

Makefile – Fehler „Keine solche Datei oder kein solches Verzeichnis vorhanden“

Ich versuche, ein Makefile-Ziel zu erstellen, das zunächst prüft, ob mein Docker-Container vorhanden ist. Wenn er vorhanden ist, möchte ich den Befehl „Docker Container Restart“ ausführen, andernfalls möchte ich den Befehl „Docker Run“ ausführen, um den Container zu erstellen und zu starten.

Ich habe das Folgende codiert, erhalte aber den unten gezeigten Fehler. Das Ergebnis = 1 ist korrekt, da ich einen Container laufen habe. Ich habe den Container entfernt und getestet, dass das Ergebnis dann 0 wird, was auch korrekt ist. Das Problem scheint aufzutreten, wenn ich versuche, result in der ifeqAnweisung zu verwenden. Kann mir bitte jemand sagen, was ich falsch mache? (Ich habe die Docker-Befehle vorübergehend auskommentiert und sie durch echo true / false ersetzt, während ich debugge).

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

Ausgabe vom Terminal

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

Antwort1

Es gibt eine Reihe von Problemen mit Ihrem Makefile (über die Frage hinaus, ob ein Makefile die geeignete Lösung ist):

  • Bedingte Anweisungen sind nicht Teil eines Rezepts und dürfen daher nicht mit einem Tab beginnen.
  • bedingte Anweisungen werden beim Lesen des Makefiles ausgewertet, daher müssen Variablen zuvor zugewiesen werden und können nicht zielspezifisch sein;
  • docker ps -agibt Informationen zu allen bekannten Containern zurück, einschließlich nicht laufender Container;
  • falsche Ziele sollten als solche deklariert werden.

Folgende Werke:

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

Antwort2

Um einen Variablenwert innerhalb eines Ziels festzulegen, müssen Sie die evalfolgende Syntax verwenden:

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

Alternativ können Sie diese Variable auch außerhalb einer Regel auswerten:

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

start_docker_myapp:        
    @echo "result is " result
    endif

Antwort3

Anstatt eine Mischung aus Shell-Skriptcode und Make-Variablen zu implementieren, schlage ich vor, dies als reines Shell-Skript zu implementieren, das in integriert ist Makefile.

Anstatt die Ausgabe von zu prüfen grepund wcdie Nummer zu vergleichen, können Sie einfach grepden Exit-Code von prüfen.

# 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

Oder mit Booleschen Operatoren anstelle vonif...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)

verwandte Informationen