Expansão de Parâmetros do bash — Entendendo ${var:-x} e Sintaxes Relacionadas

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.gz

Remover 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/docs

Padrõ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 baz

Substituiçã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^^}   # ALICE

Receitas Práticas

Obter e trocar extensão de arquivo

file="image.png"
ext=${file##*.}        # png
base=${file%.*}        # image
new="${base}.webp"     # image.webp

Valores 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.com

Normalizar nível de log para minúsculas

level="WARNING"
echo ${level,,}   # warning

Nome de arquivo seguro (substituir espaços por underscores)

filename="my report 2026.txt"
safe=${filename// /_}   # my_report_2026.txt

Próximas Leituras