Códigos de saída e tratamento de erros

ShellBeginner
Pratique Agora

Introdução

Imagine que, sempre que você pedisse a alguém para realizar uma tarefa, essa pessoa entregasse um pequeno cartão depois.

  • Um Cartão Verde (0) significa: "Fiz tudo perfeitamente."
  • Um Cartão Vermelho (1-255) significa: "Algo deu errado."

No Linux, cada comando faz exatamente isso. Esse valor é chamado de código de saída ou status de saída.

  • 0: Sucesso.
  • Diferente de 0: Falha.

A maioria dos iniciantes ignora esses códigos porque eles geralmente ficam invisíveis, a menos que você peça para vê-los. Profissionais que escrevem scripts prestam muita atenção a eles, pois o status de saída é uma das principais formas que o shell usa para informar sucesso ou falha entre comandos e scripts.

Esse é um padrão fundamental do Unix: programas pequenos se comunicam usando convenções simples. O texto pode passar pela saída padrão, enquanto o sucesso ou a falha é informado pelo status de saída. É por isso que os códigos de saída são tão importantes na automação.

Neste laboratório, você aprenderá a ler esses cartões secretos usando a variável $? e a interromper seus scripts antes que eles causem problemas.

Verifique o status dos comandos com $?

Como você pode ver esse "cartão de pontuação" invisível? Basta consultar uma variável especial chamada $? logo depois de executar um comando.

Vamos começar observando um caso de sucesso.

Abra o terminal e liste seus arquivos:

ls -l

Funcionou, certo? Agora, vamos perguntar: "Qual foi a pontuação?"

echo $?

Você deverá ver 0. Na lógica do Linux, 0 é a quantidade de erros. Zero erros significa sucesso total.

Agora, vamos forçar uma falha. Tente listar um arquivo que não existe:

ls ghosts.txt

O Linux informará que não consegue encontrar o arquivo. Agora, consulte a pontuação novamente:

echo $?

Você verá 2. Como esse valor não é 0, o comando falhou.

O número exato diferente de zero pode variar conforme o comando e a situação. Por enquanto, a regra principal é simples: 0 significa sucesso, e qualquer outro valor significa falha. Mais adiante, ao trabalhar com scripts e ferramentas, você verá que alguns programas usam códigos diferentes de zero para descrever tipos distintos de problemas.

Regra crucial: $? é uma memória de curto prazo. Ele registra apenas a última coisa que você fez. Se você executar ls (com falha), depois executar echo "hello" e só então consultar $?, verá 0, porque o echo foi executado com sucesso! Você precisa verificar o valor imediatamente.

Crie um script que falha

Aqui está a parte perigosa. Por padrão, um script ignora os cartões vermelhos. Ele simplesmente continua executando.

Imagine um script que faça o seguinte:

  1. Criar um backup.
  2. Excluir os arquivos originais.

Se a etapa 1 falhar porque o backup está cheio, a etapa 2 ainda será executada, e você perderá tudo.

Vamos simular esse "script cego".

Crie copy_script.sh:

nano copy_script.sh

Digite este código. Ele tenta copiar um arquivo inexistente e depois informa que a execução foi concluída com sucesso.

#!/bin/bash

## Attempt to copy a ghost
cp ghost_file.txt destination.txt

## Print a happy message
echo "Script finished execution"

Salve e saia. Torne o arquivo executável:

chmod +x copy_script.sh

Execute o script:

./copy_script.sh

Você verá a mensagem de erro do cp, mas depois também verá "Script finished execution". O script falhou, mas continuou executando!

Verifique a pontuação do próprio script:

echo $?

O resultado será 0. Por quê? Porque o último comando (echo) foi executado com sucesso. Esse script está mentindo: ele falhou em sua tarefa principal, mas informou sucesso ao sistema.

Esta é uma lição importante: um script de shell também tem um status de saída. Se você não fizer nada de especial, esse status geralmente será o status de saída do último comando executado. Por isso, um script pode ocultar acidentalmente uma falha ocorrida anteriormente.

Implemente o tratamento de erros

Precisamos ensinar nosso script a parar diante de um sinal vermelho.

Em geral, usamos a seguinte estrutura: "Tente executar o comando X. Se o código de saída NÃO for 0, entre em modo de emergência."

A sintaxe [ $? -ne 0 ] usa o comando test, escrito aqui no formato de colchetes. Para números, -ne significa "diferente de". Portanto, o shell está perguntando: "O status de saída do comando anterior é diferente de zero?"

Edite o script copy_script.sh:

nano copy_script.sh

Altere o conteúdo para:

#!/bin/bash

cp ghost_file.txt destination.txt

## Check if the score is NOT equal (-ne) to 0
if [ $? -ne 0 ]; then
  echo "Error: The copy operation failed!"
  exit 1
fi

echo "Script finished execution"

Entendendo o código:

  • if [ $? -ne 0 ]: A verificação consulta o cartão.
  • exit 1: O botão vermelho. Ele encerra o script imediatamente e define a pontuação global como 1 (erro).

O comando exit encerra o script de shell atual e retorna esse número ao processo que o iniciou, como o terminal, outro script ou um sistema de automação. Em outras palavras, você não está apenas interrompendo a execução localmente; também está informando o status ao ambiente externo.

Salve e saia.

Execute o script novamente:

./copy_script.sh

O script exibirá o erro e será encerrado. Ele não exibirá "Script finished execution".

Verifique a pontuação:

echo $?

O resultado será 1. Agora o script informa honestamente que falhou.

Resumo

Você aprendeu a interpretar a linguagem secreta dos comandos.

Neste laboratório, você praticou:

  1. Ler cartões de pontuação: usar $? para verificar se um comando teve sucesso (0) ou falhou (1-255).
  2. Desmascarar scripts mentirosos: entender como os scripts podem ocultar erros se você não tiver cuidado.
  3. Usar árbitros: usar exit 1 para interromper o jogo quando ocorre uma falta.

Esse padrão de "verificar e sair" é o que diferencia um script frágil de um script profissional.