Wie kann ich Trap-Fehler und Unterbrechungen in GNU machen?
Frage
Ich frage mich, ob es einen Weg gibt trap
in GNU make
, ähnlich wie in BASH
gebaut implementieren?
Wenn der Benutzer drückt CTRL-C
, oder wenn make
selbst ausfällt (Nicht-Null-Ausgang), würde Ich mag ein bestimmtes Ziel oder Makro aufrufen.
Lösung
Nein. GNU Make die Signalverarbeitung lässt schon viel zu wünschen übrig. Innerhalb seiner Signal-Handler, ruft es Funktionen wie printf
, die nicht sicher sind aus einem Signal-Handler aufgerufen werden. Ich habe dies zu Problemen führt, gesehen, zum Beispiel .DELETE_ON_ERROR
Regeln läuft nicht immer, wenn stderr
zu stdout
umgeleitet wird.
Zum Beispiel auf einem CentOS 7.4 Box:
-
Erstellen Sie die folgende
Makefile
:.DELETE_ON_ERROR: foo: touch $@ sleep 10
-
Öffnen Sie es in
vim
und Lauf:make
, - Während es schläft, drücken Sie die Strg - C
Vim / Marke druckt
Press ENTER or type command to continue
touch foo
sleep 10
^C
shell returned 130
Interrupt: Press ENTER or type command to continue
Jetzt wurde ein Interrupt-Signal gesendet, aber foo
noch existiert.
Andere Tipps
Zu diesem Zeitpunkt GNU make nicht über native Unterstützung.
Es gibt eine zuverlässige Abhilfe jedoch:
.PHONY: internal-target external-target
external-target:
bash -c "trap 'trap - SIGINT SIGTERM ERR; <DO CLEANUP HERE>; exit 1' SIGINT SIGTERM ERR; $(MAKE) internal-target"
internal-target:
echo "doing stuff here"
Dies fängt Unterbrechungen, Kündigungen und alle Nicht-Null-Exit-Codes.
Beachten Sie die $(MAKE)
so cmdline Überschreibungen und machen Optionen submake bekommen übergeben.
Auf trap:
- clear-Trap-Handler (mit -)
- Sie die Bereinigung
- Ausfahrt mit Nicht-Null-Exit-Status, so bauen Automatisierungs-Tools berichten die ausgefallenen Build.
DELETE_ON_ERROR für Verzeichnisse nicht funktioniert, so dass dies ist der Schlüssel für die Zeit nach mktemp -d
Reinigung, zum Beispiel
Ersetzen <DO CLEANUP HERE>
mit gültigen CMD.
Eine vereinfachte Version von @ kevinf Antwort, die für grundlegende Fälle gut genug scheint:
run:
bash -c "trap 'docker-compose down' EXIT; docker-compose up --build"
(Dieses Beispiel ist aus einem Grund: docker-compose up
sagt
Wenn der Befehl beendet wird, werden alle Container gestoppt.
aber es rm
nicht gestoppt Container wie docker run --rm
würde, so können Sie immer noch mit docker ps -a
sehen.)
Jetzt unterstützt es nicht, aber mit BASH Tricks, die Sie etwas Ähnliches erreichen kann.
default: complete
complete: do_mount
echo "Do something here..."
do_mount:
mkdir -p "$(MOUNTPOINT)"
( while ps -p $$PPID >/dev/null ; do \
sleep 1 ; \
done ; \
unmount "$(MOUNTPOINT)" \
) &
mount "$(MOUNTSOURCE)" "$(MOUNTPOINT)" -o bind
Die „aushängen“ wird nach der „make“ laufen abgeschlossen ist. Dies ist in der Regel eine befriedigende Lösung, wenn Sie Bereinigungsvorgänge versuchen, die während des Build auftreten können, sind aber normalerweise nicht auf „make“ exit gereinigt.
Nein. Soweit ich weiß, gibt es keine solche Funktionalität.
make erzeugt Rückgabecodes. Soweit ich jetzt erinnern kann, gibt es 0 für Erfolg, 2 für Fehler (bitte in der Dokumentation überprüfen). Daher wäre es genug für Sie, zum Beispiel in einem Shell-Skript machen wickeln?