exceções ao ERR trap

0

Estou usando uma interceptação ERR para detectar qualquer erro no meu script e gerar o que aconteceu com o log. (semelhante a essa pergunta: Armadilha, ERR e ecoando a linha de erro ) Funciona como esperado. O único problema é que, em algum momento do meu script, espera-se que um exitcode! = 0 aconteça. Como posso fazer com que a armadilha não seja acionada nesta situação?

Aqui está um código:

err_report() {
    echo "errexit on line $(caller)" | tee -a $LOGFILE 1>&2
}

trap err_report ERR

Depois, no script:

<some command which occasionally will return a non-zero exit code>

if [ $? -eq 0 ]; then
    <handle stuff>
fi

Toda vez que o comando retorna diferente de zero, minha armadilha é acionada. Posso evitar isso apenas para esta parte do código?

Eu verifiquei esta questão: Comportamento correto das armadilhas EXIT e ERR ao usar 'set -eu' mas eu não estou realmente conseguindo aplicá-lo ao meu caso - se for aplicável.

    
por masgo 31.05.2018 / 23:24

3 respostas

1

Um ERR trap não será acionado se um código de erro for imediatamente "capturado", o que significa que você pode usar as declarações if e outros sem ter que ativar a detecção de erros fora o tempo todo. No entanto, você não pode usar a verificação de $? para o controle de fluxo, porque conforme o tempo que você chega a essa verificação, você já (pode) ter o erro não detectado.

Se você tiver um comando que espera falhar - e você não deseja que as falhas disparem o trap , você simplesmente terá que detectar a falha. Envolvê-los em uma instrução if é desajeitado e detalhado, mas essa abreviação funciona bem:

/bin/false || :  # will not trigger an ERR trap

No entanto, se você quiser fazer alguma coisa quando um comando falhar, if ficará bem aqui:

if ! /bin/false; then
    echo "this was not caught by the trap!"
fi

Ou, como alternativa, else também detectará o estado do erro:

if /bin/false; then
    : # dead code
else
    echo "this was not caught by the trap!"
fi

Em suma, set -e e trap "command" ERR só são desarmados se houver uma condição de erro que não é imediatamente considerada intrinsecamente.

    
por 01.06.2018 / 00:26
2

O ERR trap obedece às mesmas regras de set -e , isto é, não tem efeito nos comandos que são usados como condições. Então,

trap "echo error" ERR
false                     # this should trigger the trap
if ! false; then          # this shouldn't
     echo handle stuff
fi

Lembre-se de que o comando na condição if pode ser qualquer comando, não precisa ser [ .. ] . Portanto, se você quiser apenas uma avaliação verdadeira / falsa do status de saída de um comando, basta usá-lo diretamente na condição if .

Se você precisar salvar o código de saída e evitar a ERR trap, precisará fazer algo como

somecmd && :; ret=$?

Aqui, o && vai esmagar o ERR trap, mas como ele só é executado se o código de saída for zero, saberemos que o código de saída é o mesmo depois de : .

Você pode querer verificar BashFAQ 105: Por que não definir -e (ou set -o errexit, ou trap ERR) o que eu esperava?

    
por 31.05.2018 / 23:31
1

Você pode ativar / desativar o ERR trap durante partes do código, conforme necessário.

#!/bin/bash
err_report() {
    echo "errexit on line $(caller)"
}
trap err_report ERR
trap - ERR             # disable ERR trap
false
if [ $? -eq 0 ]; then
    printf "OK\n"
else
    printf "FAIL\n"    # prints FAIL
fi
trap err_report ERR    # enable ERR trap
false                  # prints errexit on line 14
    
por 31.05.2018 / 23:48

Tags