⬅ Voltar ao Dashboard 2º Bimestre — Shell Script

🔄 Estrutura case/esac

Aula 10 — Múltiplas escolhas de forma elegante: padrões, wildcards e menus interativos em Shell Script

🎯 O que é a Estrutura case?

O case é uma alternativa ao if/elif/else quando se precisa comparar uma variável com muitos valores diferentes. É mais legível, organizado e fácil de manter do que uma cadeia longa de elif.

Estrutura básica

sintaxe
case "$VARIAVEL" in padrão1) comandos ;; padrão2) comandos ;; *) # caso padrão — captura o que não foi previsto comandos ;; esac

Palavras-chave essenciais

ElementoSignifica
caseInicia a estrutura
in"Em qual desses padrões se encaixa?"
)Finaliza a declaração do padrão
;;Encerra o bloco de comandos daquele caso
esacFecha a estrutura (case ao contrário!)

💡 Quando usar? 4 ou mais opções • menus interativos • classificar valores por padrão • interpretar exit codes. Para 2–3 condições simples, o if/else continua sendo mais direto.

🚀 Primeiro Exemplo: Menu Simples

menu.sh
#!/bin/bash echo "=== MENU ===" echo "1 - Incluir" echo "2 - Remover" echo "3 - Listar" read -p "Opção: " OPC case "$OPC" in 1) echo "Incluindo registro..." ;; 2) echo "Removendo registro..." ;; 3) echo "Listando registros..." ;; *) echo "Opção '$OPC' inválida! Use: 1, 2 ou 3" ;; esac

📌 O *) é a rede de segurança: captura qualquer valor que não tenha sido previsto nos casos anteriores. Sempre coloque-o por último — se vier antes, impede que os outros casos executem.

🎨 Padrões e Wildcards

O case não compara apenas valores exatos — ele trabalha com padrões, similar ao globbing do bash.

PadrãoCombina com…Exemplo
valorValor literal exato1) → só "1"
*Qualquer coisa (0 ou + chars)*) → tudo
?Exatamente um caractere?) → "a", "1", "@"
[0-9]Um dígito (0 a 9)[0-9]) → "3"
[A-Z]Uma letra maiúscula[A-Z]) → "B"
[a-z]Uma letra minúscula[a-z]) → "k"
*.txtQualquer coisa terminando em .txt*.sh) → "run.sh"
a|b|ca OU b OU cs|S|sim)

Exemplo: detector de tipo de caractere

detector.sh
read -p "Digite um caractere: " C case "$C" in [0-9]) echo "📊 É um número!" ;; [A-Z]) echo "🔤 Letra maiúscula!" ;; [a-z]) echo "🔡 Letra minúscula!" ;; *) echo "❓ Caractere especial!" ;; esac

⚠️ [0-9] captura apenas um dígito. Para detectar números de vários algarismos, use [0-9]* (um dígito seguido de qualquer coisa).

🔀 Múltiplas Opções com |

O | funciona como OU dentro de um padrão: o caso executa se a variável combinar com qualquer das alternativas.

confirmar.sh
read -p "Continuar? (sim/não): " R case "$R" in sim|SIM|s|S|yes|y|Y) echo "✅ Continuando..." ;; nao|NAO|não|n|N|no|No) echo "❌ Operação cancelada!" ;; *) echo "❓ Responda sim ou não" ;; esac

Com isso, o usuário pode digitar sim, SIM, s, S, yes ou y — todos caem no mesmo bloco. Sem o |, seria necessário um elif para cada um.

💡 Essa técnica é muito usada em scripts de instalação e configuração para aceitar confirmações em diferentes formatos, tornando o script mais robusto.

🚦 CASE com Exit Codes e CASE vs IF

Interpretando exit codes com case

Salve o exit code em $? logo após o comando e use o case para tratar cada resultado possível.

ping-check.sh
read -p "Host: " HOST ping -c 3 "$HOST" >/dev/null 2>&1 CODIGO=$? case $CODIGO in 0) echo "✅ Host $HOST está acessível!" ;; 1) echo "❌ Sem resposta de $HOST" ;; *) echo "⚠️ Erro ao executar ping: $CODIGO" ;; esac

⚠️ Salve $? imediatamente! Qualquer comando executado entre o programa e o case sobrescreve o valor de $?. Atribua a uma variável na linha seguinte ao comando.

Quando usar CASE vs IF

✅ Use case quando…

  • Há 4 ou mais opções possíveis
  • Criando menus interativos
  • Comparando padrões / wildcards
  • Uma variável contra muitos valores fixos
  • Interpretando exit codes

🔄 Use if quando…

  • Há 2–3 opções simples
  • Precisa de comparações numéricas (-gt, -le)
  • Usa operadores lógicos AND/OR
  • Testa propriedades de arquivos (-f, -d)

📌 Regra de ouro: "Comparando uma variável com muitos valores fixos?" → use case. Os dois se complementam: use case para escolher a ação principal e if para validações dentro de cada caso.

🔧 Exemplos Práticos Completos

Detector de extensão de arquivo

extensao.sh
#!/bin/bash # Identifica o tipo de arquivo pela extensão read -p "Nome do arquivo: " ARQ case "$ARQ" in *.txt|*.doc|*.docx|*.pdf) echo "📄 Documento de texto" ;; *.jpg|*.png|*.gif|*.bmp) echo "🖼️ Arquivo de imagem" ;; *.mp3|*.wav|*.ogg|*.flac) echo "🎵 Arquivo de áudio" ;; *.mp4|*.avi|*.mkv|*.mov) echo "🎬 Arquivo de vídeo" ;; *.sh) echo "⚡ Script Shell" ;; *) echo "❓ Tipo desconhecido" ;; esac

Menu de gerenciamento com case + if combinados

gerenciador.sh
#!/bin/bash # CASE para o menu principal, IF para validação interna echo "1) Listar arquivos 2) Criar arquivo 3) Info q) Sair" read -p "Escolha: " OPC case "$OPC" in 1) ls -la ;; 2) read -p "Nome do arquivo: " NOME if [ -z "$NOME" ]; then echo "Nome não pode ser vazio!" else touch "$NOME" && echo "✅ $NOME criado!" fi ;; 3) echo "Usuário: $(whoami)" echo "Data: $(date '+%d/%m/%Y %H:%M')" ;; q|Q|quit|sair) echo "👋 Até logo!" exit 0 ;; *) echo "❌ Opção inválida!" ;; esac

📋 Resumo: Padrões do case

valor Literal Valor exato
* Qualquer Zero ou + chars
? Um char Qualquer um
[0-9] Dígito Um número
[A-Za-z] Letra Maiúsc. ou minúsc.
*.ext Extensão Qualquer .ext
a|b|c OU Múltiplas opções
;; Fim do caso Obrigatório!
esac Fecha tudo case ao contrário
estrutura completa
case "$VAR" in exato) comandos ;; # valor literal a|b|c) comandos ;; # múltiplas alternativas [0-9]) comandos ;; # range de um char *.txt) comandos ;; # wildcard de extensão *) comandos ;; # padrão — SEMPRE por último! esac

🎯 Exercício — Arraste e Conecte

Relacione cada elemento do case à sua função.

Função
Fecha a estrutura case (palavra-chave final)
Encerra o bloco de comandos de cada caso
Captura qualquer valor não previsto — deve ser o último
Representa um dígito de 0 a 9
Permite múltiplas alternativas no mesmo caso (OU lógico)
Combina qualquer nome terminado em .sh
Elemento
esac
;;
*)
[0-9]
a|b|c
*.sh

🛠️ Atividade Prática — Menus e Classificadores

⏱ ~25 min 💻 Terminal Bash 📸 Tirar screenshot da saída
1
Menu simples com case
Crie menu.sh com 4 opções (listar, criar, remover, sair) usando case. O caso *) deve exibir as opções válidas. Teste com opções válidas e inválidas.
2
Validador sim/não
Crie confirmar.sh que aceite sim, SIM, s, S como confirmação e nao, n, N como negação usando o operador |. Tire screenshot dos testes.
3
Detector de extensão
Crie tipo.sh que recebe o nome de um arquivo e usa *.ext para identificar: imagem (jpg/png), áudio (mp3/wav), script (.sh) e tipo desconhecido. Teste com pelo menos 5 arquivos diferentes.
4
CASE com exit code
Crie ping.sh que faça ping -c 1 em um host digitado pelo usuário, capture o exit code em $? e use case para exibir: "Acessível" (0), "Sem resposta" (1) ou "Erro" (*).
📌 Para refletir: O case transforma um encadeamento confuso de elif em algo legível e fácil de manter. Menus interativos são um dos usos mais comuns em scripts de administração de sistemas Linux.

❓ Verifique seu Conhecimento

Qual a vantagem da estrutura case sobre múltiplos if/elif?

Acase é mais rápido que if em todos os casos
Bcase é mais legível quando há muitas opções para um mesmo valor
Ccase suporta mais operadores lógicos
Dcase pode testar variáveis numéricas, if não pode
case é ideal para comparar uma variável com múltiplos padrões — código mais limpo e organizado que encadeamentos de if/elif.

O que representa o padrão *) em uma estrutura case?

ACorresponde apenas a strings vazias
BCorresponde a qualquer número
CCorresponde a qualquer valor não tratado pelos casos anteriores
DTermina a estrutura case
*) é o padrão coringa — funciona como o else do if, capturando qualquer valor que não combinou com os padrões anteriores.

O que o duplo ponto-e-vírgula (;;) indica em uma estrutura case?

AFim de um bloco de comandos para aquele padrão
BConcatena dois comandos no mesmo padrão
CIndica que dois padrões compartilham os mesmos comandos
DEncerra toda a estrutura case
;; finaliza o bloco de cada caso, equivalente ao break em outras linguagens. Sem ele, Bash pode cair no próximo caso.

Como criar um menu interativo combinando case com while?

ANão é possível combinar case com while
BO while deve ficar dentro de cada bloco do case
CUse case dentro do while com break no padrão *)
DLoop while com read e case sobre a variável lida
✓ Padrão clássico: while true; do read opcao; case $opcao in 1) .;; q) break;; esac; done — menu que repete até o usuário sair.