Nesta aula, você vai dominar duas ferramentas essenciais do Bash para trabalhar com blocos de texto: here documents (here docs) e here strings. Esses recursos permitem redirecionar múltiplas linhas de entrada para comandos, funções ou variáveis sem a necessidade de arquivos temporários ou manipulação manual de pipes. Eles são amplamente utilizados em scripts para gerar relatórios, configurar programas interativos, alimentar loops e muito mais.

Entender here documents e here strings é fundamental para escrever scripts mais limpos, legíveis e portáveis. Vamos explorar a sintaxe básica, variações importantes e casos de uso práticos que você encontrará em ambientes reais de automação e administração de sistemas.

<<EOF

O here document (ou heredoc) é uma forma de redirecionar um bloco de texto diretamente para a entrada padrão de um comando. A sintaxe é <<MARCADOR, onde MARCADOR é uma palavra qualquer (geralmente EOF, mas pode ser qualquer string sem espaços). O Bash lê tudo que está entre a linha do marcador e a linha que contém apenas o marcador de fechamento, e envia esse conteúdo para o comando.

O here document é especialmente útil quando você precisa passar múltiplas linhas de entrada para um comando que normalmente leria de um arquivo ou do teclado. Por exemplo, você pode usar um here document para alimentar o comando cat, criar um arquivo de configuração, ou até mesmo executar SQL dentro de um script.

#!/bin/bash
# Exemplo básico de here document
cat <<EOF
Este é um texto
com várias linhas.
EOF

No exemplo acima, o comando cat recebe o texto entre os marcadores e o imprime na saída padrão. Você pode redirecionar essa saída para um arquivo usando o operador > no final do here document, como em cat <<EOF > arquivo.txt.

Uma característica importante do here document é que ele expande variáveis e comandos dentro do texto, a menos que você use aspas no marcador de abertura. Por exemplo, se você escrever <<'EOF', o conteúdo será tratado literalmente, sem expansão. Isso é útil quando você quer evitar a interpretação de caracteres especiais.

<<-EOF

O here document com hífen (<<-EOF) é uma variação que remove todos os caracteres de tabulação (TAB) do início de cada linha do conteúdo. Isso é útil para manter o código do script indentado, melhorando a legibilidade, sem que essas tabulações apareçam no texto final.

Essa variação é especialmente vantajosa quando o here document está dentro de uma estrutura indentada, como um loop ou uma função. Sem o hífen, o conteúdo do here document começaria na coluna zero, o que pode quebrar a formatação visual do script.

#!/bin/bash
# Exemplo com <<-EOF
if true; then
    cat <<-EOF
        Este texto está indentado com TABs.
        Eles serão removidos.
    EOF
fi

No exemplo, as linhas do here document estão indentadas com tabulações, mas graças ao hífen, o cat recebe o texto sem esses espaços iniciais. Repare que as linhas de conteúdo podem ter tabulações adicionais no início; todas elas serão removidas. O marcador de fechamento também deve estar indentado com TABs, e o Bash o reconhece mesmo assim.

É importante notar que apenas tabulações (caractere TAB) são removidas, não espaços. Se você usar espaços para indentar, o hífen não terá efeito. Portanto, ao usar <<-EOF, certifique-se de usar TABs no seu editor ou ajuste o comportamento conforme necessário.

Here strings (<<<)

O here string é uma forma mais compacta de enviar uma única string (ou variável) para a entrada padrão de um comando. A sintaxe é <<< palavra, onde palavra pode ser uma string literal, uma variável ou a saída de um comando entre aspas. O Bash adiciona automaticamente uma nova linha no final da string.

Here strings são extremamente úteis para passar dados para comandos que esperam entrada padrão, como grep, sed, awk, bc e muitos outros, sem a necessidade de um here document completo.

#!/bin/bash
# Exemplo de here string
variavel="Olá, mundo"
cat <<< "$variavel"
# Também funciona com strings diretas:
grep "mundo" <<< "Olá, mundo"

No exemplo, o comando cat recebe o conteúdo da variável variavel e o imprime. Já o grep busca a palavra "mundo" na string fornecida. Note que as aspas duplas ao redor da variável são importantes para preservar espaços e caracteres especiais.

Uma aplicação comum de here strings é com o comando read, para atribuir valores a variáveis sem precisar de um pipe. Por exemplo: read nome <<< "João Silva". Isso é mais eficiente do que usar um pipe, porque o pipe cria um subshell e as variáveis atribuídas dentro dele não persistem no shell atual.

Casos de uso

Here documents e here strings são versáteis e aparecem em muitos cenários de scripting. A seguir, alguns casos de uso comuns:

  • Criação de arquivos de configuração: Você pode gerar arquivos de configuração completos dentro do script, sem depender de arquivos externos. Ex.: cat <<EOF > /etc/meuapp.conf.
  • Alimentar comandos interativos: Comandos como ftp, telnet ou mysql podem receber comandos via here document, automatizando sessões interativas.
  • Gerar relatórios ou e-mails: Montar mensagens de e-mail com múltiplas linhas usando here document e passá-las para o comando mail.
  • Loop de leitura: Combinar here document com while read para processar linhas de texto sem criar um arquivo temporário.
  • Passar dados para calculadoras: Usar here string com bc para realizar cálculos matemáticos de forma rápida.
  • Evitar subshells: Em loops, usar here string com read evita a criação de subshells, permitindo que variáveis sejam modificadas no shell atual.
#!/bin/bash
# Exemplo: gerar um arquivo de configuração
cat <<EOF > app.conf
[banco]
host=localhost
porta=5432
usuario=admin
EOF

# Exemplo: usar here string com bc
resultado=$(bc <<< "scale=2; 10/3")
echo "Resultado: $resultado"

# Exemplo: loop com here document
while IFS= read -r linha; do
    echo "Linha: $linha"
done <<EOF
primeira linha
segunda linha
terceira linha
EOF

Boas práticas e observações finais

Ao trabalhar com here documents e here strings, algumas boas práticas podem evitar erros comuns:

  • Sempre escolha um marcador único e descritivo (como EOF, FIM, etc.) para evitar conflitos com o conteúdo.
  • Use aspas no marcador de abertura (<<'EOF') quando não quiser expansão de variáveis ou comandos.
  • Lembre-se de que o here document com hífen remove apenas tabulações, não espaços. Prefira TABs para indentação.
  • Em here strings, use aspas duplas para preservar espaços e evitar interpretação indesejada de caracteres especiais.
  • Evite usar here documents para textos muito grandes se o desempenho for crítico; nesses casos, considere arquivos temporários.

Esses recursos são poderosos e, quando usados corretamente, tornam seus scripts mais legíveis e eficientes. Pratique com os exemplos e exercícios abaixo para fixar o conhecimento.

Referências

Exercícios

  1. Exercício 1: Crie um script que use um here document para gerar um arquivo chamado mensagem.txt contendo três linhas de texto de sua escolha. Em seguida, exiba o conteúdo do arquivo com cat.

✓ Resposta:
#!/bin/bash
cat <<EOF > mensagem.txt
Linha um
Linha dois
Linha três
EOF
cat mensagem.txt
  1. Exercício 2: Escreva um script que use um here document com hífen (<<-EOF) dentro de uma função para imprimir uma lista de itens, garantindo que a indentação do código não apareça na saída.

✓ Resposta:
#!/bin/bash
imprimir_lista() {
    cat <<-EOF
        Item 1
        Item 2
        Item 3
    EOF
}
imprimir_lista
  1. Exercício 3: Utilize um here string para passar a string "12345" para o comando rev e exibir o resultado (deve ser "54321").

✓ Resposta:
rev <<< "12345"
  1. Exercício 4: Crie um script que use um here document para executar uma sequência de comandos SQL com o comando mysql, criando uma tabela e inserindo dados, sem precisar de um arquivo SQL externo.

✓ Resposta:
#!/bin/bash
mysql -u usuario -p senha <<EOF
CREATE DATABASE exemplo;
USE exemplo;
CREATE TABLE pessoas (id INT, nome VARCHAR(50));
INSERT INTO pessoas VALUES (1, 'João'), (2, 'Maria');
EOF
  1. Exercício 5: Explique a diferença entre <<EOF e <<'EOF' no que diz respeito à expansão de variáveis. Dê um exemplo prático mostrando a diferença.

✓ Resposta: Quando o marcador de abertura é escrito sem aspas (<<EOF), o Bash expande variáveis (como $VAR) e comandos (como $(comando)) dentro do conteúdo. Já com aspas (<<'EOF'), o conteúdo é tratado literalmente, sem qualquer expansão. Exemplo:
nome="Mundo"
# Com aspas: imprime $nome literalmente
cat <<'EOF'
Olá, $nome
EOF
# Sem aspas: imprime "Olá, Mundo"
cat <<EOF
Olá, $nome
EOF