Na programação em Bash, um "here document" (ou "heredoc") redireciona várias linhas de entrada para um comando ou programa, como se você estivesse digitando diretamente no terminal. É uma ferramenta poderosa para embutir texto de várias linhas nos seus scripts sem precisar de arquivos externos ou de manipulação complexa de strings.
Delimitador: um heredoc começa com o operador << seguido de uma palavra delimitadora (muitas vezes chamada de "marcador" ou "terminador").
Esse delimitador pode ser qualquer palavra que você escolher, mas é comum usar algo como EOF, END ou TEXT para maior clareza.
Para um código mais legível, você pode usar algo descritivo como delimitador, por exemplo END_INSTALLATION_INSTRUCTIONS.
Conteúdo: depois do << DELIMITER inicial, você escreve o conteúdo que quer redirecionar.
Pode ser várias linhas de texto, código ou qualquer outra coisa.
Terminação: o heredoc termina quando a palavra delimitadora aparece de novo em uma linha sozinha, sem espaços em branco antes ou depois.
command << DELIMITER
Content line 1
Content line 2
...
Content line N
DELIMITER
<< DELIMITER inicial e o DELIMITER final.cat << EOF
This is the first line.
This is the second line.
This is the third line.
EOF
Saída:
This is the first line.
This is the second line.
This is the third line.
Neste exemplo:
cat é o comando.<< EOF inicia o heredoc com EOF como delimitador.EOF sozinho em uma linha encerra o heredoc.cat então exibe o conteúdo que recebeu.wc -l << END
Line 1
Line 2
Line 3
END
Saída:
3
Aqui, o wc -l conta o número de linhas.
O heredoc fornece as três linhas como entrada.
O script:
#!/usr/bin/env bash
# Script to process input
while IFS= read -r line; do
echo "Processing: $line"
done
Chame o script de um prompt interativo do bash com um heredoc:
./your_script << MY_DATA
Item 1
Item 2
Item 3
MY_DATA
Saída:
Processing: Item 1
Processing: Item 2
Processing: Item 3
O Bash realiza expansão de variáveis, substituição de comando e expansão aritmética dentro de um heredoc. Nesse sentido, os heredocs funcionam como strings entre aspas duplas.
cat << EOF
The value of HOME is $HOME
The current date is $(date)
Two plus two is $((2 + 2))
EOF
Saída:
The value of HOME is /home/glennj
The current date is Thu Apr 24 13:47:32 EDT 2025
Two plus two is 4
Quando o delimitador está entre aspas (usando aspas simples ou duplas), essas expansões não acontecem. O conteúdo é tratado de forma literal. Isso é como strings entre aspas simples.
cat << 'EOF'
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
EOF
Saída:
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
Se você usar <<- (com um hífen no final) em vez de <<, o Bash vai remover qualquer tab inicial de cada linha do heredoc.
Isso é útil para indentar o conteúdo do heredoc dentro do seu script sem afetar a saída.
# Note, the leading whitespace is tab characters only, not spaces!
# The ending delimiter can have leading tabs as well.
cat <<- END
This line has 1 leading tab.
This line has a leading tab and some spaces.
This line 2 leading tabs.
END
A saída é exibida com todos os tabs iniciais removidos:
This line has 1 leading tab.
This line has a leading tab and some spaces.
This line 2 leading tabs.
O autor não recomenda esse uso. Embora ele possa melhorar a legibilidade do script,
Um uso típico pode ser fornecer um texto de ajuda:
#!/usr/bin/env bash
usage() {
cat << END_USAGE
Refresh database tables.
usage: ${0##*/} [-h|--help] [-A|--no-archive]
where: --no-archive flag will _skip_ the archive jobs
END_USAGE
}
# ... parsing command line options here ...
if [[ $flag_help == "true" ]]; then
usage
exit 0
fi
Assim como os here documents, os here strings (ou "herestrings") fornecem entrada para um comando.
No entanto, enquanto os heredocs são fornecidos como um bloco de texto, os herestrings são fornecidos como uma única string de texto.
Here strings usam a sintaxe <<< "text".
tr 'a-z' 'A-Z' <<< "upper case this string"
Saída:
UPPER CASE THIS STRING
Ao contrário dos heredocs, nenhum delimitador final é necessário.
Você pode usar um pipeline em vez de um here string:
echo "upper case this string" | tr 'a-z' 'A-Z'
Então por que usar um here string?
Considere o caso em que você obtém a string como saída de um cálculo demorado e quer alimentar o resultado a dois comandos separados. Usando pipelines, você precisa executar o cálculo duas vezes:
some_long_running_calculation | first_command
some_long_running_calculation | second_command
Uma abordagem mais eficiente é capturar a saída do cálculo (usando substituição de comando) e usar here strings para fornecer entrada aos dois comandos seguintes:
result=$( some_long_running_calculation )
first_command <<< "$result"
second_command <<< "$result"
Aqui está uma aplicação real desse exemplo:
# initialize the output CSV file
echo "ID,VALUE" > data.csv
url='https//example.com/api/query?page=1'
while true; do
json=$( curl "$url" )
# convert the results part of the response into CSV
jq -r '.results[] | [.id, .value] | @csv' <<< "$json"
# get the URL for the next page
url=$( jq -r '.next_url // ""' <<< "$json" )
if [[ "$url" == "" ]]; then
break
fi
done >> data.csv
Repare na posição do redirecionamento de saída.
Toda a saída do laço while será anexada ao arquivo data.csv.
Como essas são apenas formas de redirecionamento, elas podem ser combinadas com outras operações de redirecionamento:
cat <<< END_OF_TEXT > output.txt
This is my important text.
END_OF_TEXT
awk '...' <<< "$my_var" >> result.csv
Here documents (ou "heredocs") são uma forma flexível e conveniente de gerenciar entrada com várias linhas em scripts Bash. Eles simplificam o processo de embutir texto e dados diretamente nos seus scripts, tornando-os mais autocontidos e fáceis de ler.
Here strings (ou "herestrings") são parecidos com here documents, mas oferecem uma sintaxe mais simples e mais dinâmica.