Próbuję poinstruować GNU Make 3.81, aby nie zatrzymywał się, jeśli polecenie się nie powiedzie (więc poprzedzam to poleceniem -
), ale chcę również sprawdzić status wyjścia dla następnego polecenia i wydrukować bardziej pouczający komunikat. Jednak mój Makefile poniżej nie działa:
$ cat Makefile
all:
-/bin/false
([ $$? -eq 0 ] && echo "success!") || echo "failure!"
$
$ make
/bin/false
make: [all] Error 1 (ignored)
([ $? -eq 0 ] && echo "success!") || echo "failure!"
success!
Dlaczego powyższy plik Makefile odzwierciedla „sukces!” zamiast „porażki!” ?
aktualizacja:
Poniżej i w odpowiedzi na zaakceptowaną odpowiedź poniżej opisano, jak należy ją napisać:
failure:
@-/bin/false && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"
success:
@-/bin/true && ([ $$? -eq 0 ] && echo "success!") || echo "failure!"
.ONESHELL:
dyrektywę..SHELLFLAGS = -ec
należy użyć. Ale w tym przypadku nie można użyć-
więcej prefiksu (do osobistego dowodu odbioru), ponieważ marka napisze, że błąd jest ignorowany, ale nadal zawiedzie cały blok. Tak,|| :
jest jednym z rozwiązań ignorowania polecenia. Ale to nie jest wieloplatformowe (Windows nie ma|| :
lub|| true
)Odpowiedzi:
Każde polecenie aktualizacji w regule Makefile jest wykonywane w osobnej powłoce. Więc $? nie zawiera statusu wyjścia poprzedniej nieudanej komendy, zawiera dowolną wartość domyślną dla $? w nowej powłoce. Właśnie dlatego twoje [$? -eq 0] test zawsze się udaje.
źródło
Test nie jest potrzebny,
$?
ponieważ&&
działa, jeśli$?
wynosi zero i||
jest przeprowadzany w przypadku niezerowej wartości zwracanej.I nie potrzebujesz minusa, ponieważ wartość zwracana do wykonania jest pobierana z ostatniego wywołania programu linii. To działa dobrze
niepowodzenie:
sukces:
Przeciwnie dzieje się: jeśli chcesz napisać własną wiadomość i zepsuć proces tworzenia z niezerową wartością, musisz napisać coś takiego:
niepowodzenie:
źródło
Z GNU wykonaj dokumentację :
Aby wykorzystać
make
status wyjścia w takim przypadku, wykonajmake
ze skryptu:I niech twój Makefile zawiera:
źródło