Here documents e here strings

1. Introdução aos Here Documents

Here documents (também chamados de heredocs) são uma construção do shell que permite fornecer múltiplas linhas de entrada diretamente no script, sem a necessidade de arquivos externos. A sintaxe básica utiliza o operador << seguido por um delimitador:

comando << DELIMITADOR
linha 1
linha 2
linha 3
DELIMITADOR

O delimitador pode ser qualquer palavra, mas as convenções mais comuns são EOF, END ou FIM. O importante é que o delimitador de fechamento esteja em uma linha isolada, sem espaços antes ou depois.

cat << EOF
Olá, mundo!
Esta é a linha 2.
EOF

Por padrão, here documents realizam expansão de variáveis e substituição de comandos. Isso significa que variáveis como $HOME e comandos entre backticks ou $() serão processados:

nome="Maria"
cat << FIM
Olá, $nome!
Seu diretório home é $HOME
Hoje é $(date +%A)
FIM

2. Controle de Expansão em Here Documents

Para inibir a expansão de variáveis e comandos, basta colocar o delimitador entre aspas simples ou duplas:

nome="João"

# Com expansão
cat << EOF
Olá, $nome
EOF

# Sem expansão
cat << 'EOF'
Olá, $nome
EOF

O primeiro exemplo exibirá "Olá, João", enquanto o segundo exibirá literalmente "Olá, $nome". Isso é particularmente útil quando você precisa incluir caracteres especiais ou variáveis que não devem ser interpretadas:

cat << 'SCRIPT'
#!/bin/bash
echo "O valor de \$PATH é: $PATH"
SCRIPT

3. Here Documents com Tabulação e Redirecionamento

O operador <<- remove automaticamente as tabulações iniciais de cada linha, permitindo uma indentação mais limpa dentro de estruturas de código:

if true; then
    cat <<- EOF
    linha indentada
    outra linha
    EOF
fi

Para redirecionar a saída de um here document para um arquivo, use > ou >>:

cat << EOF > config.txt
# Configuração do servidor
PORT=8080
HOST=localhost
DEBUG=true
EOF

Isso é extremamente útil para gerar arquivos de configuração, templates ou até scripts completos:

#!/bin/bash
cat << 'EOF' > /tmp/deploy.sh
#!/bin/bash
echo "Executando deploy..."
# Mais comandos aqui
EOF
chmod +x /tmp/deploy.sh

4. Here Strings: Sintaxe e Fundamentos

Here strings são uma variação mais concisa dos here documents, utilizando o operador <<< para passar uma única string como entrada para um comando:

comando <<< "string"

São ideais para strings curtas onde um here document seria excessivo:

# Com here string
grep "erro" <<< "Arquivo sem erros"

# Equivalente com here document
grep "erro" << EOF
Arquivo sem erros
EOF

5. Here Strings com Comandos e Variáveis

Here strings brilham quando combinados com variáveis e comandos de processamento de texto:

texto="banana,maçã,laranja"
tr ',' '\n' <<< "$texto"

Comparação entre echo | comando e comando <<<:

# Usando pipe
echo "teste@email.com" | grep -oP '[\w.]+@[\w.]+'

# Usando here string
grep -oP '[\w.]+@[\w.]+' <<< "teste@email.com"

Exemplos práticos com ferramentas comuns:

# Com sed
sed 's/erro/aviso/g' <<< "Mensagem de erro crítico"

# Com awk
awk '{print $1, $3}' <<< "João 25 Programador"

# Com cut
cut -d',' -f2 <<< "id,nome,idade"

6. Aplicações Práticas e Boas Práticas

Here documents são excelentes para gerar saída formatada:

# Gerando HTML
cat << HTML > pagina.html
<!DOCTYPE html>
<html>
<head><title>$titulo</title></head>
<body>
<h1>$cabecalho</h1>
<p>$conteudo</p>
</body>
</html>
HTML

# Gerando JSON
cat << JSON > dados.json
{
  "nome": "$usuario",
  "email": "$email",
  "ativo": true
}
JSON

Here strings são perfeitos para testes rápidos:

# Testando expressões regulares
[[ "senha123" =~ [0-9]+ ]] && echo "Contém números"

# Testando comandos
if grep -q "erro" <<< "$mensagem"; then
    echo "Erro detectado!"
fi

Boas práticas importantes:
- Use delimitadores descritivos como EOF, CONFIG, SCRIPT
- Para here documents dentro de estruturas, prefira <<- com indentação por tabs
- Sempre feche o delimitador em linha separada, sem espaços
- Use aspas no delimitador quando não quiser expansão

7. Armadilhas Comuns e Erros Frequentes

Um erro frequente é usar delimitadores que aparecem no conteúdo:

# PROBLEMA: "END" aparece no conteúdo
cat << END
O arquivo termina com END
END

Solução: use delimitadores mais específicos ou únicos:

cat << 'FIM_DO_ARQUIVO'
O arquivo termina com END
FIM_DO_ARQUIVO

Outros problemas comuns:
- Espaços após o delimitador de fechamento
- Esquecer que <<- só remove tabs, não espaços
- Assumir que here strings funcionam em shells POSIX básicos (apenas Bash e Zsh)

8. Exemplos Avançados e Combinações

Here documents podem ser aninhados com cuidado:

# Script que gera outro script
cat << 'SCRIPT' | bash
cat << 'INNER'
echo "Executado internamente"
INNER
SCRIPT

Combinando here strings com substituição de processo:

# Comparando saídas
diff <(echo "linha1") <(echo "linha1")

# Equivalente com here strings
diff <(echo "linha1") <<< "linha1"

Casos de uso em automação:

#!/bin/bash
# Gerando configuração dinâmica
cat << YAML > docker-compose.yml
version: '3'
services:
  app:
    image: $IMAGE_NAME
    ports:
      - "${PORTA_EXTERNA}:8080"
    environment:
      - DB_HOST=$DB_HOST
YAML

# Testando configuração com here strings
if yq eval '.' <<< "$(cat docker-compose.yml)" &>/dev/null; then
    echo "YAML válido!"
fi

Referências