Condicionais: if, elif, else e test

1. Introdução às Estruturas Condicionais em Bash

As estruturas condicionais são fundamentais para o controle de fluxo em scripts Bash. Elas permitem que o script tome decisões baseadas em condições específicas, executando diferentes blocos de código conforme o resultado de testes. Em Bash, a sintaxe básica do if difere significativamente de linguagens como C ou Python:

if condicao; then
    comando1
    comando2
fi

Observe que o if é finalizado com fi (if invertido). O ponto e vírgula antes de then é obrigatório quando then está na mesma linha, mas pode ser substituído por uma quebra de linha. Os espaçamentos também são críticos: faltar um espaço antes ou depois dos colchetes pode gerar erros.

2. O Comando test e Seus Operadores

O comando test é a base das condicionais em Bash. Ele avalia expressões e retorna 0 (verdadeiro) ou 1 (falso). Sintaticamente, test expressao é equivalente a [ expressao ].

Operadores numéricos:

-eq  : igual a           (equal)
-ne  : diferente de      (not equal)
-lt  : menor que         (less than)
-le  : menor ou igual    (less or equal)
-gt  : maior que         (greater than)
-ge  : maior ou igual    (greater or equal)

Operadores de string:

=    : strings iguais
!=   : strings diferentes
-z   : string vazia (zero length)
-n   : string não vazia (non-zero length)

Operadores de arquivo:

-f   : arquivo regular existe
-d   : diretório existe
-e   : arquivo existe (qualquer tipo)
-r   : arquivo tem permissão de leitura
-w   : arquivo tem permissão de escrita
-x   : arquivo tem permissão de execução

3. Usando if com test e Colchetes

Exemplo prático com colchetes simples:

#!/bin/bash
a=10
b=20

if [ "$a" -eq "$b" ]; then
    echo "a é igual a b"
else
    echo "a é diferente de b"
fi

Importância das aspas duplas: Sempre use aspas duplas em variáveis dentro de [ ]. Sem elas, se a variável estiver vazia ou contiver espaços, o script pode quebrar.

Os colchetes duplos [[ ]] são uma extensão do Bash que oferece vantagens:
- Suporte a operadores lógicos && e || diretamente
- Suporte a expressões regulares com =~
- Não requer aspas duplas para variáveis
- Comportamento mais previsível com strings vazias

if [[ "$a" -eq "$b" ]]; then
    echo "a é igual a b"
fi

# Exemplo com regex
if [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
    echo "Email válido"
fi

4. Ramificações com else e elif

A estrutura if...else fornece um caminho alternativo quando a condição falha:

if [ -f "/etc/passwd" ]; then
    echo "Arquivo encontrado"
else
    echo "Arquivo não encontrado"
fi

O elif permite encadear múltiplas condições:

#!/bin/bash
nota=75

if [ "$nota" -ge 90 ]; then
    echo "Conceito: A - Aprovado com excelência"
elif [ "$nota" -ge 70 ]; then
    echo "Conceito: B - Aprovado"
elif [ "$nota" -ge 50 ]; then
    echo "Conceito: C - Recuperação"
else
    echo "Conceito: D - Reprovado"
fi

5. Operadores Lógicos em Condicionais

Dentro de [ ], use -a (and) e -o (or):

if [ "$idade" -ge 18 -a "$possui_carteira" = "sim" ]; then
    echo "Pode dirigir"
fi

Com [[ ]], use && e ||:

if [[ "$idade" -ge 18 && "$possui_carteira" = "sim" ]]; then
    echo "Pode dirigir"
fi

Boas práticas: Para expressões complexas, prefira [[ ]] pois é mais legível e evita problemas de parsing:

if [[ ("$usuario" = "admin" || "$usuario" = "root") && -f "/etc/config" ]]; then
    echo "Acesso permitido"
fi

6. Aninhamento de Condicionais e Indentação

Estruturas if podem ser aninhadas para criar lógicas mais complexas:

#!/bin/bash
echo "Sistema de Login"
read -p "Usuário: " usuario
read -sp "Senha: " senha
echo

if [ -n "$usuario" ]; then
    if [ -n "$senha" ]; then
        if [ "$usuario" = "admin" ] && [ "$senha" = "1234" ]; then
            echo "Login bem-sucedido"
            echo "1. Ver logs"
            echo "2. Configurar sistema"
            read -p "Opção: " opcao
            if [ "$opcao" = "1" ]; then
                echo "Exibindo logs..."
            elif [ "$opcao" = "2" ]; then
                echo "Abrindo configurações..."
            else
                echo "Opção inválida"
            fi
        else
            echo "Usuário ou senha incorretos"
        fi
    else
        echo "Senha não pode estar vazia"
    fi
else
    echo "Usuário não pode estar vazio"
fi

A indentação consistente (2 ou 4 espaços) é crucial para legibilidade. Cada nível de aninhamento deve ser claramente visível.

7. Casos Especiais e Boas Práticas

Uso de exit e return para controle de fluxo:

#!/bin/bash
validar_parametro() {
    if [ -z "$1" ]; then
        echo "Erro: Parâmetro obrigatório"
        return 1
    fi
    echo "Parâmetro: $1"
    return 0
}

if ! validar_parametro "$1"; then
    exit 1
fi

Negação com !:

if [ ! -f "arquivo.txt" ]; then
    echo "Arquivo não existe"
fi

if [[ ! "$nome" =~ ^[A-Z] ]]; then
    echo "Nome deve começar com maiúscula"
fi

Armadilhas comuns:

  1. Espaçamento incorreto: [ "$a" = "$b" ] funciona, mas ["$a"="$b"] não.
  2. Esquecimento do then: Cada if e elif deve ter seu then.
  3. Variáveis não definidas: Sempre use ${var:-default} ou teste com -z.
  4. Comparar números com =: Use -eq para números, = para strings.

Dica final: Sempre valide seus scripts com:

bash -n script.sh    # Verifica sintaxe sem executar
shellcheck script.sh # Analisa boas práticas e erros comuns

Referências