Desejo gerar um erro em um script Bash com a mensagem "Casos de teste com falha !!!". Como fazer isso no Bash?
Por exemplo:
if [ condition ]; then
raise error "Test cases failed !!!"
fi
linux
bash
shell
error-handling
Naveen Kumar
fonte
fonte
echo you screwed up at ... | mail -s BUG $bugtrackeremailaddress
?Respostas:
Isso depende de onde você deseja que a mensagem de erro seja armazenada.
Você pode fazer o seguinte:
Ou o seguinte:
Ao levantar uma exceção, você interrompe a execução do programa.
Você também pode usar algo como
exit xxx
ondexxx
está o código de erro que você pode querer retornar ao sistema operacional (de 0 a 255). Aqui125
e64
são apenas códigos aleatórios que você pode sair com. Quando você precisar indicar ao SO que o programa parou de forma anormal (por exemplo, ocorreu um erro), você precisa passar um código de saída diferente de zero paraexit
.Como @chepner apontou , você pode fazer
exit 1
, o que significará um erro não especificado .fonte
1>&2
fará o truqueexit
por si só usa o status de saída do comando concluído mais recentemente, que pode ser 0.exit 1
, o que por convenção significa um erro não especificado.Tratamento básico de erros
Se o executor do caso de teste retornar um código diferente de zero para testes com falha, você pode simplesmente escrever:
Ou ainda mais curto:
Ou o mais curto:
Para sair com o código de saída de test_handler:
Tratamento avançado de erros
Se você quiser uma abordagem mais abrangente, pode ter um gerenciador de erros:
em seguida, invoque-o após executar o caso de teste:
ou
As vantagens de ter um manipulador de erros como
exit_if_error
são:if
blocos que testam códigos de saída para errosBiblioteca de tratamento e registro de erros
Aqui está uma implementação completa de tratamento de erros e registro:
https://github.com/codeforester/base/blob/master/lib/stdlib.sh
Postagens relacionadas
__FILE__
,__LINE__
em Bashfonte
Existem mais algumas maneiras de abordar esse problema. Assumindo que um de seus requisitos é executar um script / função de shell contendo alguns comandos de shell e verificar se o script foi executado com êxito e lançar erros em caso de falhas.
Os comandos do shell geralmente dependem de códigos de saída retornados para permitir que o shell saiba se foi bem-sucedido ou falhou devido a alguns eventos inesperados.
Então, o que você quer fazer recai nessas duas categorias
Dependendo de qual você deseja fazer, existem opções de shell disponíveis para uso. Para o primeiro caso, o shell oferece uma opção com
set -e
e para o segundo você pode fazer umtrap
onEXIT
Devo usar
exit
em meu script / função?O uso
exit
geralmente aumenta a legibilidade Em certas rotinas, depois de saber a resposta, você deseja sair para a rotina de chamada imediatamente. Se a rotina for definida de tal maneira que não exija nenhuma limpeza adicional depois de detectar um erro, não sair imediatamente significa que você terá que escrever mais código.Portanto, nos casos em que você precisa fazer ações de limpeza no script para fazer o encerramento do script limpo, é preferível não usar
exit
.Devo usar
set -e
para erro ao sair?set -e
foi uma tentativa de adicionar "detecção automática de erros" ao shell. Seu objetivo era fazer com que o shell abortasse sempre que um erro ocorresse, mas ele vem com muitas armadilhas potenciais, por exemplo,Os comandos que fazem parte de um teste if são imunes. No exemplo, se você espera que ele interrompa a
test
verificação do diretório inexistente, não iria, ele vai para a condição elseOs comandos em um pipeline diferente do último são imunes. No exemplo abaixo, porque o código de saída do comando executado mais recentemente (mais à direita) é considerado (
cat
) e foi bem-sucedido. Isso poderia ser evitado definindo pelaset -o pipefail
opção, mas ainda é uma advertência.Recomendado para uso -
trap
na saídaO veredicto é se você deseja ser capaz de lidar com um erro em vez de sair cegamente, em vez de usar
set -e
, use umtrap
noERR
pseudo sinal.A
ERR
armadilha não é executar o código quando o próprio shell sai com um código de erro diferente de zero, mas quando qualquer comando executado por aquele shell que não faz parte de uma condição (como em ifcmd
oucmd ||
) sai com um status de saída diferente de zero .A prática geral é definir um manipulador de trap para fornecer informações adicionais de depuração sobre qual linha e o que causa a saída. Lembre-se de que o código de saída do último comando que causou o
ERR
sinal ainda estaria disponível neste ponto.e apenas usamos este manipulador como abaixo no topo do script que está falhando
Juntando isso em um script simples que continha
false
na linha 15, as informações que você obteria comoO
trap
também fornece opções independentemente do erro para apenas executar a limpeza na conclusão do shell (por exemplo, o script de shell sai), no sinalEXIT
. Você também pode capturar vários sinais ao mesmo tempo. A lista de sinais suportados para trap pode ser encontrada na página de manual trap.1p - LinuxOutra coisa a observar seria entender que nenhum dos métodos fornecidos funciona se você estiver lidando com subshells envolvidos, nesse caso, você pode precisar adicionar seu próprio tratamento de erros.
Em um sub-shell com
set -e
não funcionaria. Ofalse
é restrito ao sub-shell e nunca é propagado para o shell pai. Para fazer o tratamento de erros aqui, adicione sua própria lógica para fazer(false) || false
O mesmo acontece com
trap
também. A lógica abaixo não funcionaria pelos motivos mencionados acima.fonte
Aqui está uma armadilha simples que imprime o último argumento de tudo o que falhou em STDERR, relata a linha em que falhou e sai do script com o número da linha como código de saída. Observe que nem sempre são ótimas ideias, mas isso demonstra alguma aplicação criativa que você pode desenvolver.
Eu coloquei isso em um script com um loop para testá-lo. Acabei de verificar se há acertos em alguns números aleatórios; você pode usar testes reais. Se eu precisar sair, chamo false (o que aciona a armadilha) com a mensagem que desejo lançar.
Para funcionalidades elaboradas, faça com que o trap chame uma função de processamento. Você sempre pode usar uma instrução case em seu arg ($ _) se precisar fazer mais limpeza, etc. Atribua a uma var para um pouco de açúcar sintático -
Saída de amostra:
Obviamente, você poderia
Muito espaço para melhorias de design.
As desvantagens incluem o fato de que
false
não é bonito (daí o açúcar), e outras coisas que acionam a armadilha podem parecer um pouco estúpidas. Mesmo assim, gosto desse método.fonte
Você tem 2 opções: redirecionar a saída do script para um arquivo, introduzir um arquivo de log no script e
Aqui, você assume que o script produz todas as informações necessárias, incluindo mensagens de aviso e erro. Você pode então redirecionar a saída para um arquivo de sua escolha.
O comando acima redireciona a saída padrão e a saída de erro para seu arquivo de log.
Usando essa abordagem, você não precisa introduzir um arquivo de log no script e, portanto, a lógica é um pouco mais fácil.
Em seu script, adicione um arquivo de log codificando-o permanentemente:
ou passando por um parâmetro:
É uma boa ideia adicionar o carimbo de data / hora no momento da execução ao arquivo de log na parte superior do script:
Você pode então redirecionar suas mensagens de erro para o arquivo de log
Isso anexará o erro ao arquivo de log e continuará a execução. Se quiser interromper a execução quando ocorrerem erros críticos,
exit
o script pode :Observe que
exit 1
indica que a execução do programa foi interrompida devido a um erro não especificado. Você pode personalizar isso se quiser.Usando essa abordagem, você pode personalizar seus logs e ter um arquivo de log diferente para cada componente de seu script.
Se você tem um script relativamente pequeno ou deseja executar o script de outra pessoa sem modificá-lo, a primeira abordagem é mais adequada.
Se você quiser que o arquivo de log esteja sempre no mesmo local, esta é a melhor opção dos dois opção.
fonte
Costumo achar útil escrever uma função para lidar com mensagens de erro para que o código seja mais limpo no geral.
Isso pega o código de erro do comando anterior e o usa como o código de erro padrão ao sair de todo o script. Ele também anota o tempo, com microssegundos onde for suportado (a data GNU
%N
é nanossegundos, que truncamos em microssegundos depois).Se a primeira opção for zero ou um inteiro positivo, torna-se o código de saída e o removemos da lista de opções. Em seguida, relatamos a mensagem para o erro padrão, com o nome do script, a palavra "ERROR" e o tempo (usamos a expansão do parâmetro para truncar nanossegundos em microssegundos, ou para tempos não GNU, para truncar, por exemplo,
12:34:56.%N
para12:34:56
). Dois pontos e espaço são adicionados após a palavra ERROR, mas apenas quando há uma mensagem de erro fornecida. Finalmente, saímos do script usando o código de saída previamente determinado, disparando quaisquer armadilhas normalmente.Alguns exemplos (suponha que o código resida
script.sh
):fonte