Operadores de comparação: numérico, string e arquivos
1. Introdução aos Operadores de Comparação
Operadores de comparação são fundamentais em scripts Bash para tomar decisões baseadas em condições. Eles permitem verificar valores numéricos, comparar strings e inspecionar propriedades de arquivos. Sem eles, scripts seriam lineares e incapazes de reagir a diferentes cenários.
A principal diferença está no tipo de dado: números são comparados com operadores específicos (-eq, -lt), enquanto strings usam operadores como = e !=. Arquivos possuem seu próprio conjunto de testes.
A estrutura básica usa [ expressão ] (comando test) ou [[ expressão ]] (palavra reservada do Bash). A versão com colchetes duplos é mais moderna, segura e flexível.
# Estrutura básica
if [ "$idade" -eq 18 ]; then
echo "Maior de idade"
fi
# Versão com [[ ]]
if [[ "$nome" == "João" ]]; then
echo "Olá, João"
fi
2. Comparação Numérica
Os operadores numéricos no Bash são mnemônicos e fáceis de lembrar:
| Operador | Significado |
|---|---|
-eq |
igual |
-ne |
diferente |
-lt |
menor que |
-le |
menor ou igual |
-gt |
maior que |
-ge |
maior ou igual |
#!/bin/bash
a=10
b=20
if [ "$a" -eq "$b" ]; then
echo "a é igual a b"
elif [ "$a" -lt "$b" ]; then
echo "a é menor que b"
fi
# Cuidado: SEMPRE usar aspas nas variáveis
valor="5"
if [ "$valor" -gt 3 ]; then
echo "$valor é maior que 3"
fi
Cuidados importantes: Sempre use aspas duplas nas variáveis. Se a variável estiver vazia, sem aspas o comando quebra. Além disso, números com zeros à esquerda (como 08) podem ser interpretados como octal em alguns contextos.
3. Comparação de Strings
Para strings, os operadores são diferentes:
| Operador | Significado |
|---|---|
= |
igual (equivalente a ==) |
!= |
diferente |
< |
menor (ordem lexicográfica) |
> |
maior (ordem lexicográfica) |
-z |
string vazia (tamanho zero) |
-n |
string não vazia |
#!/bin/bash
nome="Maria"
vazia=""
if [ "$nome" = "Maria" ]; then
echo "Nome é Maria"
fi
if [ -z "$vazia" ]; then
echo "String vazia detectada"
fi
if [ -n "$nome" ]; then
echo "String não vazia: $nome"
fi
# Comparação lexicográfica (com [[ ]] para evitar escaping)
if [[ "abc" < "def" ]]; then
echo "abc vem antes de def"
fi
Diferença entre = e ==: Em Bash, ambos funcionam com [ ] e [[ ]], mas == é preferido em [[ ]] por ser mais intuitivo. O = é o padrão POSIX.
Ordenação lexicográfica: Com [ ], os operadores < e > precisam ser escapados (\< e \>). Com [[ ]], isso não é necessário.
4. Operadores de Arquivos
O Bash oferece diversos testes para arquivos e diretórios:
Existência e tipo:
| Operador | Descrição |
|----------|-------------------------------|
| -e | arquivo existe (qualquer tipo)|
| -f | é um arquivo regular |
| -d | é um diretório |
| -L | é um link simbólico |
Permissões:
| Operador | Descrição |
|----------|-------------------------------|
| -r | tem permissão de leitura |
| -w | tem permissão de escrita |
| -x | tem permissão de execução |
Propriedades:
| Operador | Descrição |
|----------|-------------------------------|
| -s | tamanho maior que zero |
| -nt | mais recente que (newer than) |
| -ot | mais antigo que (older than) |
| -ef | mesmo arquivo (hard link) |
#!/bin/bash
arquivo="/etc/passwd"
if [ -e "$arquivo" ]; then
echo "Arquivo existe"
fi
if [ -f "$arquivo" ] && [ -r "$arquivo" ]; then
echo "É um arquivo regular legível"
fi
if [ -d "/home" ]; then
echo "/home é um diretório"
fi
# Comparação de timestamps
if [ "/tmp/novo.txt" -nt "/tmp/velho.txt" ]; then
echo "novo.txt é mais recente"
fi
# Verificar link simbólico
if [ -L "/usr/bin/python" ]; then
echo "É um link simbólico"
fi
5. Combinando Operadores com Test
Os operadores lógicos permitem criar condições complexas:
&&(AND): ambas as condições devem ser verdadeiras||(OR): pelo menos uma condição deve ser verdadeira!(NOT): inverte o resultado
#!/bin/bash
arquivo="documento.txt"
# Verificar se existe E é legível (usando [ ])
if [ -f "$arquivo" ] && [ -r "$arquivo" ]; then
echo "Arquivo existe e é legível"
fi
# Verificar se é diretório OU link simbólico
if [ -d "$arquivo" ] || [ -L "$arquivo" ]; then
echo "É diretório ou link"
fi
# Negação: verificar se NÃO é vazio
if [ ! -z "$variavel" ]; then
echo "Variável não está vazia"
fi
# Combinando múltiplos testes
if [ -f "$arquivo" ] && [ -s "$arquivo" ] && [ -w "$arquivo" ]; then
echo "Arquivo regular, não vazio e gravável"
fi
Com test explícito:
if test -f "$arquivo" && test -r "$arquivo"; then
echo "Arquivo existe e é legível"
fi
6. Expressões com [[ ]] (Bash Avançado)
O [[ ]] é uma palavra reservada do Bash que oferece vantagens significativas:
- Sem necessidade de escapar operadores
<e> - Suporte a pattern matching com
==(glob patterns) - Suporte a regex com
=~ - Operadores lógicos internos (
&&,||) sem precisar de[ ]separados - Tratamento seguro de variáveis vazias
#!/bin/bash
arquivo="script.sh"
# Pattern matching (glob)
if [[ "$arquivo" == *.sh ]]; then
echo "É um script shell"
fi
# Regex com =~
if [[ "$arquivo" =~ ^[a-z]+\.sh$ ]]; then
echo "Nome válido de script"
fi
# Operadores combinados sem escaping
if [[ -f "$arquivo" && -x "$arquivo" ]]; then
echo "Arquivo executável existe"
fi
# Comparação numérica com [[ ]]
if [[ "$(wc -l < "$arquivo")" -gt 10 ]]; then
echo "Arquivo tem mais de 10 linhas"
fi
# Expressões complexas
if [[ "$1" =~ ^[0-9]+$ ]] && [[ "$1" -gt 0 && "$1" -le 100 ]]; then
echo "Número válido entre 1 e 100"
fi
7. Erros Comuns e Boas Práticas
Erro 1: Esquecer espaços dentro dos colchetes
# ERRADO
if [$var -eq 5]; then
# CERTO
if [ "$var" -eq 5 ]; then
Erro 2: Confundir operadores numéricos com de string
# ERRADO: comparando string com operador numérico
if [ "10" -eq "10" ]; then # funciona, mas conceitualmente errado
# CERTO para strings
if [ "$a" = "$b" ]; then
# CERTO para números
if [ "$a" -eq "$b" ]; then
Erro 3: Não usar aspas em variáveis
# ERRADO: se $nome estiver vazio, quebra
if [ $nome = "João" ]; then
# CERTO
if [ "$nome" = "João" ]; then
Boas práticas:
- Sempre use [[ ]] para scripts modernos em Bash (mais seguro e flexível)
- Use aspas duplas em todas as variáveis dentro de [ ]
- Para expressões regex, use =~ com [[ ]]
- Prefira -eq para números e = para strings
- Teste sempre arquivos com -f antes de operações de leitura/escrita
Referências
- GNU Bash Manual: Conditional Constructs — Documentação oficial sobre
[[ ]],(( ))e expressões condicionais no Bash. - Advanced Bash-Scripting Guide: Operations on Variables — Guia detalhado com exemplos de operadores de comparação numérica, de strings e de arquivos.
- Linuxize: Bash Comparison Operators — Tutorial prático com exemplos claros de todos os operadores de comparação.
- ShellCheck: Tool for Shell Scripts — Ferramenta online para análise estática de scripts, ajuda a evitar erros comuns de comparação.
- Bash Hackers Wiki: Test and [ ] — Explicação detalhada do comando
teste colchetes, incluindo operadores de arquivo. - How-To Geek: How to Compare Numbers and Strings in Linux — Guia introdutório com exemplos práticos para iniciantes em Bash.