Das Ausführen (exit 1);
ist die einfachste Art, eine ERR
Falle auszulösen . Es wird auch ein sofortiges Verlassen ausgelöst, wenn dies set -e
wirksam ist. (Zum Auslösen der Fehlerbedingung muss ein Befehl fehlschlagen. exit
Wenn ein Fehlerwert in einer Subshell angegeben wird, schlägt die Subshell fehl.)
exit 1;
wird keines dieser Dinge tun.
So {(exit 1); exit 1;}
kann den zum ersten Produkten verwendet wird ERR
Fall, die für Debugging - Zwecke nützlich etwas tun könnte, und dann das Skript mit einer Fehleranzeige beenden.
Aber das ist nicht das, was in autoconf
Dateien vor sich geht. autoconf
Skripte verlassen sich auf die EXIT
Falle, um temporäre Dateien zu bereinigen, die während des Laufs erstellt wurden. Die meisten Shells, einschließlich bash
, setzen den Status anhand des im exit
Befehl angegebenen Werts, bevor sie den EXIT
Trap aufrufen . Auf diese Weise kann der EXIT
Trap erkennen, ob er aufgrund eines Fehlers oder einer normalen Beendigung aufgerufen wurde, und er kann auch sicherstellen, dass der Beendigungsstatus am Ende des Trap-Vorgangs korrekt festgelegt ist.
Anscheinend arbeiten jedoch einige Muscheln nicht zusammen. Hier ist ein Zitat aus dem autoconf
Handbuch :
Einige Shell-Skripte, beispielsweise die von generierten autoconf
, bereinigen vor dem Beenden mit einem Trap. Wenn der letzte Shell-Befehl mit einem Status ungleich Null beendet wurde, wird der Trap auch mit einem Status ungleich Null beendet, sodass der Aufrufer feststellen kann, dass ein Fehler aufgetreten ist.
Leider /bin/sh
ignoriert eine Exit-Trap in einigen Shells, wie z. B. Solaris , das Argument des Befehls exit. In diesen Shells kann ein Trap nicht feststellen, ob er durch einfaches Beenden oder durch Beenden von 1 aufgerufen wurde. Verwenden Sie den AC_MSG_ERROR
Makro, der eine Problemumgehung für dieses Problem aufweist, anstatt Exit direkt aufzurufen .
Die Problemumgehung besteht darin, vor der Ausführung des Befehls sicherzustellen, dass $?
dieser den Exit-Status hat , damit er bei der Ausführung des Traps definitiv diesen Wert hat . Und tatsächlich ist es das Makro, das diesen seltsamen Code mit redundanten Klammern einfügt.exit
EXIT
AC_MSG_ERROR
false
statt(exit 1)
?false
Sie können den Statuscode nicht festlegen, und es gibt keine Garantie dafür, welcher Nicht-Null-Status zurückgegeben wird. (2)false
ist normalerweise kein integrierter Prozess, sodass ein untergeordneter Prozess erforderlich ist. Im Gegensatz dazu können die meisten Muscheln das Laichen eines Kindes vermeiden(exit 1)
.Dies hat meines Erachtens keinen Sinn, es gibt nichts, was direkt durch Starten einer Unterschale und sofortiges Beenden erreicht werden kann.
Solche Dinge sind höchstwahrscheinlich ein Nebeneffekt der automatischen Codegenerierung. In einigen Fällen werden möglicherweise andere Befehle in der Subshell ausgeführt, wenn das
exit 1
sinnvoll ist. Letztendlich besteht eine gute Chance, dass der Generierungscode auf irgendeine Weise vereinfacht wird, indem einige Anweisungen eingefügt werden, die in einigen Fällen keine Funktion haben, und die Generierung von 'sauberem Code' jedes Mal komplexer ist. Entweder das oder der Code, der das oben Genannte generiert hat, ist nur schlecht geschrieben :)Die liberale Verwendung von
{...}
ist ein weiteres Beispiel dafür. Die meisten von ihnen sind redundant, aber es ist einfacher, Code zu schreiben, der sie in jedem Fall einfügt (in einigen Fällen möchten Sie möglicherweise die Ausgabe / Eingabe des Blocks umleiten), anstatt die zu unterscheiden diejenigen, wo sie nicht benötigt werden und lassen sie weg.quelle
(exit 1)
Dies ist ein einfacher, wahrscheinlich der einfachste Weg, einen bestimmten Exit-Code zu erhalten (im Sonderfall 1 gibt es natürlich einfachere Wege). Dies ist jedoch in diesem Fall nicht der Grund, da der Exit-Code nicht geprüft wird.Der Zweck des
exit
Einfügens einer Subshell kann darin bestehen, das Skript nicht zu beenden (obwohl exit zur Generierung eines bestimmten Beendigungscodes verwendet wird).quelle