Executar (exit 1);
é a maneira mais simples de acionar uma ERR
armadilha. Também acionará a saída imediata, se set -e
estiver em vigor. (A ativação da condição de erro requer a falha de um comando; exit
com um valor de falha em um subshell faz com que o subshell falhe.)
exit 1;
não fará nenhuma dessas coisas.
Portanto, {(exit 1); exit 1;}
pode ser usado para produzir primeiro a ERR
armadilha, o que pode ser útil para fins de depuração e, em seguida, finalizar o script com uma indicação de erro.
Mas não é isso que está acontecendo nos autoconf
arquivos. autoconf
scripts dependem da EXIT
armadilha para limpar arquivos temporários criados durante a execução. A maioria dos shells, inclusive bash
, definirá o status a partir do valor fornecido no exit
comando antes de chamar a EXIT
armadilha. Isso pode permitir que a EXIT
interceptação detecte se foi invocada a partir de um erro ou da finalização normal e também garante 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 :
Alguns scripts de shell, como os gerados por autoconf
, usam uma interceptação para limpar antes de sair. Se o último comando do shell sair com status diferente de zero, a interceptação também sairá com status diferente de zero, para que o invocador possa dizer que ocorreu um erro.
Infelizmente, em alguns shells, como o Solaris /bin/sh
, uma armadilha de saída ignora o argumento do comando exit. Nessas shells, uma interceptação não pode determinar se foi invocada pela saída simples ou pela saída 1. Em vez de chamar exit diretamente, use a AC_MSG_ERROR
macro que possui uma solução alternativa para esse problema.
A solução alternativa é garantir que $?
tenha o status de saída antes da exit
execução do comando, para que ele definitivamente tenha esse valor quando a EXIT
interceptação for executada. E, de fato, é a AC_MSG_ERROR
macro que insere esse código curioso, completo com chaves redundantes.
false
vez de(exit 1)
?false
não permite definir o código de status e não há garantia de qual status diferente de zero ele retorna. (2)false
geralmente não é um componente interno, portanto, requer um processo filho; por outro lado, a maioria das conchas pode evitar a criação de uma criança(exit 1)
.Não há nenhum objetivo para isso, tanto quanto posso ver, não há nada que possa ser alcançado diretamente iniciando um subshell e depois saindo imediatamente.
Coisas como essa provavelmente são um efeito colateral da geração automática de código - em alguns casos, pode haver outros comandos executados no subshell, onde isso
exit 1
faz sentido. Por fim, existe uma boa chance de que o código de geração seja de alguma forma simplificado, permitindo a inserção de algumas instruções que, em alguns casos, não possuem nenhuma função e gerando 'código limpo' toda vez que for mais complexo. Ou isso ou o código que gerou o texto acima está mal escrito :)O uso liberal de
{...}
é outro exemplo disso, a maioria deles é redundante, mas é mais fácil escrever código que os insere em todos os casos (talvez em alguns você queira redirecionar a saída / entrada do bloco) em vez de distinguir o aqueles onde eles não são necessários e os omitem.fonte
(exit 1)
é uma maneira simples, provavelmente a maneira mais simples de obter um determinado código de saída (no caso especial de 1, existem maneiras mais fáceis, é claro). Mas esse não é o motivo neste caso, pois o código de saída não é examinado.O objetivo de colocar
exit
um subshell pode ser não sair do script (embora use exit para a geração de um determinado código de saída).fonte