A execução de (exit 1);
é a maneira mais simples de acionar uma interceptação ERR
. Ele também acionará a saída imediata se set -e
estiver em vigor. (Disparar a condição de erro requer um comando para falhar; exit
com um valor de falha em uma subshell faz com que a subshell falhe).
exit 1;
não fará nada disso.
Portanto, {(exit 1); exit 1;}
pode ser usado para produzir primeiro a ERR
trap, que pode fazer algo útil para propósitos de depuração, e então terminar o script com uma indicação de erro.
Mas não é isso que está acontecendo em autoconf
arquivos. Os scripts autoconf
confiam no EXIT
trap para limpar os arquivos temporários criados durante a execução. A maioria dos shells, incluindo bash
, definirá o status do valor fornecido no comando exit
antes de chamar o EXIT
trap. Isso pode permitir que a interceptação EXIT
detecte se foi invocada por um erro ou por finalização normal, e também permite garantir que o status de saída seja definido corretamente no final da operação de interceptação.
No entanto, aparentemente algumas conchas não cooperam. Aqui está uma citação do autoconf
manual :
Some shell scripts, such as those generated by
autoconf
, use a trap to clean up before exiting. If the last shell command exited with nonzero status, the trap also exits with nonzero status so that the invoker can tell that an error occurred.Unfortunately, in some shells, such as Solaris
/bin/sh
, an exit trap ignores the exit command's argument. In these shells, a trap cannot determine whether it was invoked by plain exit or by exit 1. Instead of calling exit directly, use theAC_MSG_ERROR
macro that has a workaround for this problem.
A solução alternativa é certificar-se de que $?
tenha o status de saída antes de executar o comando exit
, para que ele tenha definitivamente esse valor quando a EXIT
trap for executada. E, de fato, é a macro AC_MSG_ERROR
que insere esse código curioso, completo com chaves redundantes.