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)
?