Mein Makefile ist sehr einfach:
all:
[ -f MyFile ] && echo "MyFile exists"
Natürlich beginnt die Rezeptzeile mit Tab. Wenn die Datei MyFile wirklich existiert, ist alles ok. Liegt diese Datei aber nicht im aktuellen Verzeichnis, erhalte ich:
Makefile:2: Rezept für Ziel 'all' fehlgeschlagen make: *** [all] Fehler 1
Ich kann diesen Fehler beheben, indem ich stattdessen die if-Anweisung verwende:
all:
if [ -f MyFile ]; then echo "MyFile exists"; fi
Beide Anweisungen funktionieren in sh und bash außerhalb von make einwandfrei. Mir ist nicht klar, was der Grund für den Make-Fehler ist, wenn der Bedingungsoperator verwendet wird. Eine Idee, was los ist?
Antwort1
[ -f MyFile ] && echo "MyFile exists"
wird mit einem Statuscode ungleich Null beendet, wenn MyFile
es nicht existiert, während
if [ -f MyFile ]; then echo "MyFile exists"; fi
wird mit einem erfolgreichen (Null-)Statuscode beendet, sofern nicht MyFile
vorhandenUnd echo
schlägt mit einem Schreibfehler fehl.
Make verwendet Statuscodes, um zu bestimmen, ob Befehle fehlgeschlagen sind, und stoppt die Ausführung standardmäßig, wenn ein Befehl fehlschlägt. Sie können dies für einzelne Befehlszeilen deaktivieren, indem Sie ihnen das Präfix voranstellen -
, oder insgesamt, indem Sie ausführen make -i
oder das spezielle .IGNORE
Ziel angeben. Somit
-[ -f MyFile ] && echo "MyFile exists"
würde Make erlauben, fortzufahren, würde aber trotzdem dazu führen, dass eine Meldung ausgegeben wird, wenn MyFile
es nicht existiert:
make: [Makefile:14: test] Fehler 1 (ignoriert)
Das || true
Musterwürde in diesem speziellen Fall auch funktionieren, würde aber Fehler in ignorieren echo
. if condition; then command; fi
führt nicht dazu, dass Make gestoppt wird, wenn condition
false ist, sondern berücksichtigt command
die Fehler von , während condition && command || true
alle Fehler ignoriert werden.