Dans les scripts Bash, un here document (ou heredoc) redirige plusieurs lignes d'entrée vers une commande ou un programme, comme si tu les tapais directement dans le terminal. C'est un outil puissant pour intégrer du texte multiligne dans tes scripts sans avoir besoin de fichiers externes ni de manipulations complexes de chaînes de caractères.
Délimiteur : un here document commence par l'opérateur << suivi d'un mot délimiteur (souvent appelé « marqueur » ou « terminateur »).
Ce délimiteur peut être n'importe quel mot de ton choix, mais on utilise souvent quelque chose comme EOF, END ou TEXT pour plus de clarté.
Pour un code plus lisible, tu peux utiliser un délimiteur descriptif, par exemple END_INSTALLATION_INSTRUCTIONS.
Contenu : après le << DELIMITER initial, tu écris le contenu que tu veux rediriger.
Cela peut être plusieurs lignes de texte, du code, ou n'importe quoi d'autre.
Fin : le here document se termine lorsque le mot délimiteur réapparaît seul sur une ligne, sans espace ni avant ni après.
command << DELIMITER
Content line 1
Content line 2
...
Content line N
DELIMITER
<< DELIMITER de début et le DELIMITER de fin.cat << EOF
This is the first line.
This is the second line.
This is the third line.
EOF
Sortie :
This is the first line.
This is the second line.
This is the third line.
Dans cet exemple :
cat est la commande.<< EOF démarre le here document avec EOF comme délimiteur.EOF seul sur sa ligne met fin au here document.cat affiche ensuite le contenu qu'il a reçu.wc -l << END
Line 1
Line 2
Line 3
END
Sortie :
3
Ici, wc -l compte le nombre de lignes.
Le here document fournit les trois lignes en entrée.
Le script :
#!/usr/bin/env bash
# Script to process input
while IFS= read -r line; do
echo "Processing: $line"
done
Appelle le script depuis une invite bash interactive à l'aide d'un here document :
./your_script << MY_DATA
Item 1
Item 2
Item 3
MY_DATA
Sortie :
Processing: Item 1
Processing: Item 2
Processing: Item 3
Bash effectue l'expansion des variables, la substitution de commandes et l'expansion arithmétique à l'intérieur d'un here document. En ce sens, les here documents se comportent comme des chaînes de caractères entre guillemets doubles.
cat << EOF
The value of HOME is $HOME
The current date is $(date)
Two plus two is $((2 + 2))
EOF
Sortie :
The value of HOME is /home/glennj
The current date is Thu Apr 24 13:47:32 EDT 2025
Two plus two is 4
Quand le délimiteur est mis entre guillemets (simples ou doubles), ces expansions sont désactivées. Le contenu est pris littéralement. C'est comme les chaînes de caractères entre guillemets 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
Sortie :
The value of $HOME is not expanded here.
The result of $(date) is not executed.
Two plus two is calculated by $((2 + 2))
Si tu utilises <<- (avec un tiret final) au lieu de <<, Bash supprime tous les caractères de tabulation en début de chaque ligne du here document.
C'est pratique pour indenter le contenu du here document dans ton script sans que cela change la sortie.
# 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
La sortie s'affiche avec toutes les tabulations initiales supprimées :
This line has 1 leading tab.
This line has a leading tab and some spaces.
This line 2 leading tabs.
L'auteur ne recommande pas cette utilisation. Même si elle peut améliorer la lisibilité du script,
Un cas d'usage typique consiste à fournir un texte d'aide :
#!/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
Comme les here documents, les here strings (ou herestrings) fournissent une entrée à une commande.
Cependant, alors que les here documents sont fournis sous forme de bloc de texte, les here strings sont fournis sous forme d'une seule chaîne de caractères.
Les here strings utilisent la syntaxe <<< "text".
tr 'a-z' 'A-Z' <<< "upper case this string"
Sortie :
UPPER CASE THIS STRING
Contrairement aux here documents, aucun délimiteur de fin n'est nécessaire.
On peut utiliser un pipeline à la place d'un here string :
echo "upper case this string" | tr 'a-z' 'A-Z'
Alors pourquoi utiliser un here string ?
Imagine que tu obtiens la chaîne en sortie d'un calcul long, et que tu veux transmettre le résultat à deux commandes distinctes. Avec des pipelines, tu dois exécuter le calcul deux fois :
some_long_running_calculation | first_command
some_long_running_calculation | second_command
Une approche plus efficace consiste à capturer la sortie du calcul (avec la substitution de commandes), puis à utiliser des here strings pour fournir l'entrée aux deux commandes suivantes :
result=$( some_long_running_calculation )
first_command <<< "$result"
second_command <<< "$result"
Voici une application concrète de cet exemple :
# 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
Remarque la position de la redirection de sortie.
Toute la sortie de la boucle while sera ajoutée au fichier data.csv.
Comme ce ne sont que des formes de redirection, on peut les combiner avec d'autres opérations de redirection :
cat <<< END_OF_TEXT > output.txt
This is my important text.
END_OF_TEXT
awk '...' <<< "$my_var" >> result.csv
Les here documents (ou heredocs) sont un moyen souple et pratique de gérer des entrées multilignes dans les scripts Bash. Ils simplifient l'intégration de texte et de données directement dans tes scripts, ce qui les rend plus autonomes et plus faciles à lire.
Les here strings (ou herestrings) sont semblables aux here documents, mais offrent une syntaxe plus simple et plus dynamique.