Heredoc: Como Incorporar Strings Multilinhas em Scripts Shell

Heredoc: Como Incorporar Strings Multilinhas em Scripts Shell

O que e um Heredoc?

Um heredoc (here document) permite incorporar strings multilinhas diretamente em um script shell. Ele comeca com <<DELIMITADOR e termina quando o delimitador aparece sozinho em uma linha. Comparado a encadear multiplas chamadas echo, heredocs sao muito mais legveis e sao amplamente usados para gerar arquivos de configuracao, executar consultas SQL e enviar comandos via SSH.

Sintaxe Basica

Escreva <<DELIMITADOR, depois o corpo do texto, e em seguida o delimitador de fechamento em sua propria linha.

cat <<EOF
Primeira linha de texto
Segunda linha de texto
Terceira linha de texto
EOF
Primeira linha de texto
Segunda linha de texto
Terceira linha de texto

O delimitador pode ser qualquer string -- EOF, END, HEREDOC -- mas EOF (End Of File) e a escolha convencional.

O delimitador de fechamento deve comecar na coluna zero. Quaisquer espacos ou tabs iniciais impedirao seu reconhecimento, fazendo o script travar aguardando entrada.

A Expansao de Variaveis Esta Ativada por Padrao

Com <<EOF (sem aspas), variaveis e substituicoes de comando dentro do heredoc sao expandidas pelo shell antes da saida.

NAME="Alice"
TODAY=$(date +%Y-%m-%d)
cat <<EOF
Ola, $NAME
Hoje e $TODAY
EOF
Ola, Alice
Hoje e 2026-06-01

Para desativar a expansao, coloque o delimitador entre aspas simples.

NAME="Alice"
cat <<'EOF'
Ola, $NAME
$(date) nao e expandido
EOF
Ola, $NAME
$(date) nao e expandido

Quando usar qual

  • Incorporar variaveis shell na saida -> <<EOF (padrao)
  • Exibir um template ou trecho de codigo literalmente -> <<'EOF'

Remover Tabs Iniciais com <<-

Um heredoc padrao preserva todos os espacos em branco iniciais. Com <<-, apenas caracteres tab iniciais sao removidos. Isso permite indentar o corpo do heredoc para combinar com o codigo ao redor sem que a indentacao apareca na saida.

if true; then
	cat <<-EOF
	Bloco indentado
	Tabs sao removidos da saida
	EOF
fi
Bloco indentado
Tabs sao removidos da saida

Apenas caracteres tab (\t) sao removidos -- nao espacos. Se seu editor usa indentacao com espacos, voce precisa converter essas linhas para tabs para que o <<- funcione.

Escrevendo em Arquivos

Combine um heredoc com redirecionamento para gerar arquivos de configuracao diretamente a partir de um script.

cat <<EOF > /tmp/config.conf
host=localhost
port=5432
dbname=mydb
EOF

Para adicionar ao inves de sobrescrever, use >>:

cat <<EOF >> /tmp/config.conf
user=admin
password=secret
EOF

Para arquivos que precisam de permissoes root, passe pelo sudo tee. Usar sudo cat <<EOF > /root/file nao funciona porque o shell abre o alvo do redirecionamento antes do sudo ter efeito.

cat <<EOF | sudo tee /etc/myapp/config.conf
host=localhost
port=5432
EOF

Exemplo Pratico -- Executando Comandos via SSH

ssh user@server <<EOF
echo "Iniciando deploy"
cd /var/www/myapp
git pull origin main
systemctl restart myapp
EOF

Use <<EOF quando quiser que as variaveis sejam expandidas localmente antes de a string ser enviada ao shell remoto. Use <<'EOF' quando quiser que o shell remoto as expanda.

Exemplo Pratico -- Enviando Consultas ao MySQL

mysql -u root -p mydb <<EOF
SELECT id, name FROM users WHERE active = 1;
UPDATE users SET last_login = NOW() WHERE id = 42;
EOF

Esse padrao e comum em scripts de inicializacao e jobs em lote que precisam executar multiplas instrucoes SQL em uma unica sessao.

Armadilhas Comuns

Sem espacos ou tabs antes do delimitador de fechamento

# Errado: o EOF de fechamento tem espacos iniciais e nunca e reconhecido
cat <<EOF
conteudo
  EOF
EOF

O delimitador de fechamento deve comecar na coluna zero (ou use <<- apenas com tabs).

Escapando cifrao para saida literal

Com <<EOF (expansao ativada), prefixe $ com uma barra invertida para exibi-lo literalmente.

cat <<EOF
Variavel do diretorio home: \$HOME
Valor real: $HOME
EOF
Variavel do diretorio home: $HOME
Valor real: /home/alice

Capturando um heredoc em uma variavel

Para armazenar um heredoc em uma variavel ao inves de canaliza-lo para um comando, use substituicao de comando com $().

TEXT=$(cat <<EOF
texto
multilinha
armazenado em uma variavel
EOF
)
echo "$TEXT"

Proximas Leituras