L'exécution (exit 1);
est le moyen le plus simple de déclencher une ERR
interruption. Il déclenchera également une sortie immédiate s'il set -e
est en vigueur. (Le déclenchement de la condition d'erreur nécessite l'échec d'une commande; exit
une valeur d'échec dans un sous-shell entraîne l'échec du sous-shell.)
exit 1;
ne fera rien de ces choses.
Donc, {(exit 1); exit 1;}
peut être utilisé pour produire d'abord le ERR
piège, ce qui pourrait faire quelque chose d'utile à des fins de débogage, puis terminer le script avec une indication d'erreur.
Mais ce n'est pas ce qui se passe dans les autoconf
fichiers. autoconf
les scripts s'appuient sur le EXIT
piège pour nettoyer les fichiers temporaires créés pendant l'exécution. La plupart des shells, y compris bash
, définiront l'état à partir de la valeur fournie dans la exit
commande avant d'appeler l' EXIT
interruption. Cela pourrait permettre à l' EXIT
interruption de détecter si elle a été invoquée à partir d'une erreur ou d'une terminaison normale, et cela lui permet également de s'assurer que l'état de sortie est correctement défini à la fin de l'opération d'interruption.
Cependant, apparemment, certains obus ne coopèrent pas. Voici une citation du autoconf
manuel :
Certains scripts shell, tels que ceux générés par autoconf
, utilisent un piège pour nettoyer avant de quitter. Si la dernière commande shell s'est terminée avec un état différent de zéro, l'interruption se termine également avec un état différent de zéro afin que l'appelant puisse dire qu'une erreur s'est produite.
Malheureusement, dans certains shells, tels que Solaris /bin/sh
, un piège de sortie ignore l'argument de la commande exit. Dans ces shells, une interruption ne peut pas déterminer si elle a été invoquée par une sortie standard ou par la sortie 1. Au lieu d'appeler directement la sortie, utilisez la AC_MSG_ERROR
macro qui a une solution de contournement pour ce problème.
La solution de contournement consiste à s'assurer qu'il $?
a le statut de sortie avant l' exit
exécution de la commande, afin qu'il ait définitivement cette valeur lors de l' EXIT
exécution de l'interruption. Et, en effet, c'est la AC_MSG_ERROR
macro qui insère ce code curieux, complet avec des accolades redondantes.
false
au lieu de(exit 1)
?false
ne vous permet pas de définir le code d'état et il n'y a aucune garantie quant à l'état non nul qu'il renvoie. (2)false
n'est généralement pas intégré, il nécessite donc un processus enfant; en revanche, la plupart des coquilles peuvent éviter de donner naissance à un enfant à manipuler(exit 1)
.Pour autant que je sache, il n'y a aucun but, il n'y a rien qui puisse être réalisé directement en démarrant un sous-shell puis en quittant immédiatement.
Des choses comme celle-ci sont très probablement un effet secondaire de la génération automatique de code - dans certains cas, il peut y avoir d'autres commandes exécutées dans le sous-shell où avoir le
exit 1
sens. En fin de compte, il y a de fortes chances que le code de génération soit en quelque sorte simplifié en lui permettant d'insérer des instructions qui n'ont aucune fonction dans certains cas plutôt et en générant du `` code propre '' à chaque fois est plus complexe. Soit cela, soit le code qui a généré ce qui précède est mal écrit :)L'utilisation libérale de
{...}
est un autre exemple de cela, la plupart d'entre eux sont redondants, mais il est plus facile d'écrire du code qui les insère dans tous les cas (peut-être dans certains, vous voulez rediriger la sortie / entrée du bloc) plutôt que de distinguer le ceux où ils ne sont pas nécessaires et les omettre.la source
(exit 1)
est un moyen simple, probablement le plus simple d'obtenir un certain code de sortie (dans le cas spécial de 1, il existe des moyens plus faciles, bien sûr). Mais ce n'est pas la raison dans ce cas car le code de sortie n'est pas examiné.Le but de mettre
exit
un sous-shell peut être de ne pas quitter le script (bien qu'en utilisant exit pour la génération d'un certain code de sortie).la source