Expansão de Parâmetros do bash — Entendendo ${var:-x} e Sintaxes Relacionadas
O Que é Expansão de Parâmetros?
A expansão de parâmetros do bash (${var}) vai muito além da simples substituição de variáveis. Você pode definir valores padrão, extrair substrings, remover prefixos e sufixos por padrão, realizar substituições e alterar maiúsculas/minúsculas — tudo sem iniciar processos externos como sed ou awk.
Guia de Referência Completo
| Sintaxe | Comportamento |
|---|---|
${var} |
Expande variável (chaves evitam ambiguidade) |
${var:-val} |
Retorna val se não definida ou vazia (sem atribuição) |
${var:=val} |
Atribui e retorna val se não definida ou vazia |
${var:+val} |
Retorna val se definida e não vazia |
${var:?msg} |
Imprime msg no stderr e sai se não definida ou vazia |
${#var} |
Comprimento do valor da variável |
${var:N} |
Substring do offset N até o final |
${var:N:L} |
Substring do offset N com comprimento L |
${var#pat} |
Remove menor prefixo correspondente a pat |
${var##pat} |
Remove maior prefixo correspondente a pat |
${var%pat} |
Remove menor sufixo correspondente a pat |
${var%%pat} |
Remove maior sufixo correspondente a pat |
${var/pat/rep} |
Substitui primeira correspondência de pat por rep |
${var//pat/rep} |
Substitui todas as correspondências de pat por rep |
${var/#pat/rep} |
Substitui pat apenas se ancorado no início |
${var/%pat/rep} |
Substitui pat apenas se ancorado no final |
${var^} |
Primeira letra maiúscula (Bash 4+) |
${var^^} |
Todas maiúsculas (Bash 4+) |
${var,} |
Primeira letra minúscula (Bash 4+) |
${var,,} |
Todas minúsculas (Bash 4+) |
Padrões de Valor Padrão (:- / := / :+ / :?)
Estes quatro operadores lidam de forma limpa com o problema "e se a variável não estiver definida?".
${var:-val} — Retorna val se não definida ou vazia
O operador mais comum. Retorna val quando var não está definida ou está vazia. Não modifica var.
name=${1:-"world"}
echo "Hello, ${name}!"
# Sem argumento → Hello, world!
# Argumento "Alice" → Hello, Alice!LOG_DIR=${LOG_DIR:-/var/log/myapp}
echo "Logging to: ${LOG_DIR}"${var:=val} — Atribui val se não definida ou vazia
Como :-, mas também atribui val a var. A variável mantém o valor para uso subsequente.
: ${TMPDIR:=/tmp}
echo "${TMPDIR}" # /tmp (se nao estava definida):= não funciona com parâmetros posicionais ($1, $2, etc.). Use :- para esses.
${var:+val} — Retorna val se definida e não vazia
O inverso de :-. Retorna val somente quando var está definida e não vazia.
VERBOSE=1
msg="Done${VERBOSE:+ (verbose mode)}"
echo "$msg" # Done (verbose mode)
unset VERBOSE
msg="Done${VERBOSE:+ (verbose mode)}"
echo "$msg" # Done${var:?msg} — Sai com erro se não definida ou vazia
Impõe variáveis obrigatórias. Imprime msg no stderr e sai com status 1.
#!/bin/bash
set -e
DB_HOST=${DB_HOST:?"DB_HOST is not set"}Combine com set -u para a disciplina mais rigorosa de variáveis; :? adiciona uma mensagem personalizada que set -u sozinho não pode fornecer.
Comprimento de String e Extração de Substring
${#var} — Comprimento da String
str="Hello, World"
echo ${#str} # 12${var:N:L} — Substring
Extrai L caracteres começando no offset N. Omita L para ir até o final.
date_str="2026-06-02"
echo ${date_str:0:4} # 2026 (ano)
echo ${date_str:5:2} # 06 (mes)
echo ${date_str:8} # 02 (dia)Para offsets negativos (contar do final), escreva ${var: -2} com um espaço, ou ${var:(-2)}. Sem o espaço, ${var:-2} é o operador de "valor padrão", não um offset negativo.
str="Hello"
echo ${str: -3} # llo (ultimos 3 caracteres)Remoção de Padrão (# / ## / % / %%)
Ideal para remover componentes de caminho e extensões de arquivo sem chamar basename ou dirname.
Remover prefixo (# / ##)
${var#pat}— remove o menor prefixo correspondente a pat${var##pat}— remove o maior prefixo correspondente a pat
path="/home/user/docs/report.txt"
echo ${path#*/} # home/user/docs/report.txt (remove / inicial)
echo ${path##*/} # report.txt (remove tudo ate a ultima /)Alternativa portável ao basename:
file="/home/user/docs/report.tar.gz"
echo ${file##*/} # report.tar.gzRemover sufixo (% / %%)
${var%pat}— remove o menor sufixo correspondente a pat${var%%pat}— remove o maior sufixo correspondente a pat
file="report.tar.gz"
echo ${file%.*} # report.tar (remove ultima extensao)
echo ${file%%.*} # report (remove todas as extensoes)Alternativa portável ao dirname:
path="/home/user/docs/report.txt"
echo ${path%/*} # /home/user/docsPadrões suportam globs. ${var#*_} remove até e incluindo o primeiro _; ${var##*_} remove até e incluindo o último _.
Substituição de Padrão (/ / //)
${var/pat/rep} — Substituir primeira correspondência
msg="foo bar foo"
echo ${msg/foo/baz} # baz bar foo${var//pat/rep} — Substituir todas as correspondências
msg="foo bar foo"
echo ${msg//foo/baz} # baz bar bazSubstituição ancorada
str="foo-bar-foo"
echo ${str/#foo/baz} # baz-bar-foo (apenas no inicio)
echo ${str/%foo/baz} # foo-bar-baz (apenas no final)Padrões são padrões glob, não expressões regulares. Para correspondência com regex, use [[ $str =~ pattern ]].
Conversão de Maiúsculas/Minúsculas (Bash 4+)
Estes operadores requerem Bash 4.0 ou posterior. macOS vem com Bash 3.x por padrão; use brew install bash ou zsh para acessar esses recursos.
| Sintaxe | Comportamento | Exemplo |
|---|---|---|
${var^} |
Primeira letra maiúscula | hello --> Hello |
${var^^} |
Todas maiúsculas | hello --> HELLO |
${var,} |
Primeira letra minúscula | HELLO --> hELLO |
${var,,} |
Todas minúsculas | HELLO --> hello |
name="alice"
echo ${name^} # Alice
echo ${name^^} # ALICEReceitas Práticas
Obter e trocar extensão de arquivo
file="image.png"
ext=${file##*.} # png
base=${file%.*} # image
new="${base}.webp" # image.webpValores padrão de argumentos de script
#!/bin/bash
ENV=${1:-production}
PORT=${2:-8080}
echo "Starting: env=${ENV} port=${PORT}"Impor variáveis de ambiente obrigatórias
#!/bin/bash
: ${API_KEY:?"API_KEY is not set. Run: export API_KEY=..."}
: ${DB_URL:?"DB_URL is not set"}Extrair domínio de uma URL
url="https://example.com/path/to/page"
no_proto=${url#*://} # example.com/path/to/page
domain=${no_proto%%/*} # example.comNormalizar nível de log para minúsculas
level="WARNING"
echo ${level,,} # warningNome de arquivo seguro (substituir espaços por underscores)
filename="my report 2026.txt"
safe=${filename// /_} # my_report_2026.txt