Estou tentando obter o código de saída da função que estou chamando repetidamente na parte "condition" de um while
loop Bash:
while <function>; do
<stuff>
done
Quando esse loop termina devido a um erro, preciso do código de saída de <function>
. Alguma ideia de como posso conseguir isso?
Você pode capturar o valor de saída da condição e propagá-lo para frente:
Resultado
Nesse caso, o status de saída de
rmdir FOO
foi capturado na variávelss
e é1
. (Tente substituirrmdir FOO
por( exit 4 )
. Você descobrirá quess=4
.)Como é que isso funciona? Lembre-se de que a sintaxe é realmente
while list-1; do list-2; done
, e não a expectativa muito mais usual dewhile command; do list; done
. Olist-1
pode ser uma sequência de comandos separados por ponto e vírgula, e a documentação afirma que o "while
comando executa continuamente a listalist-2
, desde que o último comando na listalist-1
retorne um status de saída igual a zero " .Como uma apresentação alternativa da
while
condição de aparência confusa, é possível atribuir uma variável enquanto estiver dentro de uma expressão(( ... ))
e, em seguida, usar o resultado. Isso fornece a estrutura de atribuição e teste mais difícil de ler, mas mais compacta:Alternativamente, você pode usar
while rmdir FOO; ! (( ss=$? ))
. Eles funcionam porque ((1)) avalia aritmeticamente para 1, que geralmente é associado a true, e assim o código de saída dessa avaliação é 0 (sucesso). Por outro lado, ((0)) avalia aritmeticamente para 0, que geralmente está associado a falso, e assim o código de saída dessa avaliação é 1 (falha). Isso pode parecer confuso, pois afinal ambas as avaliações((.))
são "bem-sucedidas", mas este é um truque para trazer o valor das expressões aritméticas que representam verdadeiro/falso de acordo com os códigos de saída de sucesso/falha do bash e fazer expressões condicionais comoif ...; then ...; fi
,while ...; do ...; done
, etc. , funcionam corretamente, seja com base em códigos de saída ou valores aritméticos.Uma maneira de fazer isso é fazer o teste explicitamente em vez de delegá-lo ao
while
. Então, o seguinte deve fazer:No início do loop (a priori infinito) você executaria o comando de condição "manualmente" e armazenaria o código de saída, verificaria e sairia do loop se for diferente de zero (indicando falha). Somente se for zero você executa o código de loop "real".
A sintaxe pode ser "compactada" porque (como observado por @roaima) você pode ter atribuições de variáveis dentro da
(( ... ))
construção de teste aritmético.Crie uma função de encapsulamento que defina uma variável com o resultado do código de saída de sua função. Exemplo:
Com
zsh
, você pode usarreturn
de uma função anônima:Com qualquer shell do tipo Bourne, você sempre pode usar uma função nomeada: