Case statement em Bash
1. Introdução ao Case Statement
O comando case é uma estrutura de controle condicional presente no Bash que permite comparar uma variável ou expressão contra múltiplos padrões de forma clara e eficiente. Diferentemente de longas cadeias de if-elif-else, o case oferece uma sintaxe mais legível e enxuta para situações onde se deseja testar diversos valores possíveis para uma mesma variável.
A sintaxe básica do case segue o seguinte formato:
case expressao in
padrao1)
comandos
;;
padrao2)
comandos
;;
*)
comandos_padrao
;;
esac
A principal vantagem do case sobre o if-elif-else é a clareza visual: cada padrão é claramente delimitado, e o uso do ;; evita ambiguidades sobre onde termina cada bloco de comandos. Além disso, o case suporta padrões com curingas, tornando-o mais flexível para correspondências parciais.
2. Sintaxe e Estrutura do Case
A estrutura do case é composta por palavras-chave específicas:
case: inicia o bloco, seguido pela expressão a ser avaliadain: separa a expressão dos padrões;;: finaliza cada bloco de comandos de um padrãoesac: fecha o blococase(é "case" ao contrário)
Os padrões podem ser literais, curingas ou combinações:
#!/bin/bash
fruta="banana"
case $fruta in
"maca")
echo "É uma maçã"
;;
"banana"|"laranja")
echo "É uma banana ou laranja"
;;
*)
echo "Fruta desconhecida"
;;
esac
O padrão *) funciona como um "else" genérico, capturando qualquer valor que não corresponda aos padrões anteriores. É boa prática sempre incluir um padrão curinga ao final.
3. Padrões com Caracteres Curinga
O Bash permite o uso de caracteres curinga dentro dos padrões do case, seguindo as regras de globbing:
*: corresponde a qualquer sequência de caracteres?: corresponde a exatamente um caractere|: combina múltiplos padrões em um único bloco
#!/bin/bash
read -p "Digite um nome de arquivo: " arquivo
case $arquivo in
*.txt)
echo "Arquivo de texto"
;;
*.jpg|*.png|*.gif)
echo "Arquivo de imagem"
;;
arquivo?)
echo "Arquivo com nome de 8 caracteres"
;;
*)
echo "Tipo desconhecido"
;;
esac
Note que arquivo? corresponderia a "arquivo1", "arquivoA", mas não a "arquivo" ou "arquivo12". O curinga ? é útil para validar formatos específicos de entrada.
4. Case com Expressões Regulares e Globbing
É importante entender que o case do Bash utiliza globbing (expansão de padrões de arquivos) e não expressões regulares. No globbing, podemos usar classes de caracteres entre colchetes:
[abc]: corresponde a 'a', 'b' ou 'c'[0-9]: corresponde a qualquer dígito[[:alpha:]]: corresponde a qualquer letra[[:upper:]]: corresponde a letras maiúsculas
#!/bin/bash
read -p "Digite uma senha: " senha
case $senha in
[0-9]*)
echo "Senha começa com número"
;;
[[:upper:]]*)
echo "Senha começa com letra maiúscula"
;;
?[[:digit:]])
echo "Senha tem 2 caracteres e o segundo é dígito"
;;
*)
echo "Formato não identificado"
;;
esac
Diferentemente das expressões regulares, no globbing não usamos âncoras como ^ ou $. O padrão é aplicado contra a string inteira.
5. Case com Variáveis e Argumentos de Script
O case é extremamente útil para processar argumentos de linha de comando e criar menus interativos:
#!/bin/bash
# Processando argumentos do script
case $1 in
-h|--help)
echo "Uso: $0 [OPCAO]"
echo "Opções:"
echo " -h, --help Mostra esta ajuda"
echo " -v, --version Mostra a versão"
echo " -l, --list Lista itens"
;;
-v|--version)
echo "Script versão 1.0"
;;
-l|--list)
for item in "$@"; do
[ "$item" = "$1" ] && continue
echo "Item: $item"
done
;;
*)
echo "Opção inválida: $1"
echo "Use $0 --help para ajuda"
exit 1
;;
esac
Para menus interativos com read:
#!/bin/bash
echo "=== MENU PRINCIPAL ==="
echo "1) Iniciar serviço"
echo "2) Parar serviço"
echo "3) Status do serviço"
echo "4) Sair"
read -p "Escolha uma opção: " opcao
case $opcao in
1)
echo "Iniciando serviço..."
# Comando para iniciar
;;
2)
echo "Parando serviço..."
# Comando para parar
;;
3)
echo "Verificando status..."
# Comando para status
;;
4|s|S|sair|SAIR)
echo "Saindo..."
exit 0
;;
*)
echo "Opção inválida!"
;;
esac
6. Boas Práticas e Armadilhas Comuns
Esquecer o ;;: Este é o erro mais comum. Sem o ;;, o Bash continua executando os comandos do próximo padrão (fall-through):
# ERRADO - sem ;;
case $var in
a)
echo "Opção A"
# Falta o ;;
b)
echo "Opção B" # Será executado mesmo se $var for "a"
;;
esac
Ordem dos padrões: Coloque padrões mais específicos antes dos genéricos:
# ERRADO - padrão genérico antes
case $ext in
*)
echo "Tipo desconhecido"
;;
.txt)
echo "Arquivo texto" # Nunca será executado
;;
esac
Uso do esac: Lembre-se que esac é obrigatório para fechar o bloco. É uma palavra invertida de case, fácil de memorizar.
7. Exemplos Práticos e Aplicações
Script de menu de sistema (start/stop/status):
#!/bin/bash
SERVICO="apache2"
case $1 in
start)
echo "Iniciando $SERVICO..."
systemctl start $SERVICO
;;
stop)
echo "Parando $SERVICO..."
systemctl stop $SERVICO
;;
restart)
echo "Reiniciando $SERVICO..."
systemctl restart $SERVICO
;;
status)
systemctl status $SERVICO
;;
*)
echo "Uso: $0 {start|stop|restart|status}"
exit 1
;;
esac
Validação de entrada do usuário (sim/não/sair):
#!/bin/bash
read -p "Deseja continuar? (s/n/sair): " resposta
case $resposta in
s|S|sim|SIM|Sim)
echo "Continuando execução..."
;;
n|N|nao|NAO|Nao)
echo "Operação cancelada."
;;
sair|exit|quit)
echo "Encerrando script."
exit 0
;;
*)
echo "Resposta inválida. Use s, n ou sair."
;;
esac
Processamento de extensões de arquivo:
#!/bin/bash
for arquivo in "$@"; do
case "$arquivo" in
*.txt)
echo "Processando $arquivo como texto..."
cat "$arquivo"
;;
*.jpg|*.jpeg|*.png)
echo "Processando $arquivo como imagem..."
file "$arquivo"
;;
*.pdf)
echo "Processando $arquivo como PDF..."
pdftotext "$arquivo" - | head -5
;;
*.sh)
echo "Verificando sintaxe do script $arquivo..."
bash -n "$arquivo"
;;
*)
echo "Extensão não reconhecida para $arquivo"
;;
esac
done
O case no Bash é uma ferramenta poderosa que, quando bem utilizada, torna scripts mais legíveis, organizados e fáceis de manter. Combinado com curingas e classes de caracteres, oferece flexibilidade para lidar com uma ampla gama de padrões de entrada, superando as limitações de cadeias longas de if-elif-else.
Referências
- Bash Reference Manual: Conditional Constructs (case) — Documentação oficial da GNU sobre o comando
casee outras estruturas condicionais no Bash - Linuxize: Bash case Statement — Tutorial completo com exemplos práticos do uso do
caseem scripts Bash - Shell Scripting Tutorial: Case Statement — Guia didático abordando desde o básico até padrões avançados com curingas
- How-To Geek: How to Use Case Statements in Bash Scripts — Artigo explicativo com exemplos de menus interativos e processamento de argumentos
- Bash Hackers Wiki: The case Statement — Referência técnica detalhada sobre sintaxe, padrões e comportamentos específicos do
case