Parcours
/
Bash
Bash
/
Programme
/
Here documents
He

Here documents en Bash

{one: "%{count} exercice", many: "%{count} d'exercices", other: "%{count} exercices"}

À propos de Here documents

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.

Caractéristiques principales et syntaxe

  1. 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.

  2. 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.

  3. 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.

Syntaxe de base

command << DELIMITER
  Content line 1
  Content line 2
  ...
  Content line N
DELIMITER

Comment ça marche

  • Bash lit toutes les lignes entre le << DELIMITER de début et le DELIMITER de fin.
  • Bash connecte ce contenu à l'entrée standard de la commande.
  • La commande traite cette entrée comme si elle venait du clavier.

Exemple 1 : sortie de texte simple

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.
  • Les trois lignes de texte constituent le contenu.
  • EOF seul sur sa ligne met fin au here document.
  • cat affiche ensuite le contenu qu'il a reçu.

Exemple 2 : utilisation avec wc (comptage de mots)

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.

Exemple 3 : transmettre des données à un script

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

Variantes et fonctionnalités avancées

Contenu littéral

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))

Suppression des tabulations initiales

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.
Caution

L'auteur ne recommande pas cette utilisation. Même si elle peut améliorer la lisibilité du script,

  1. il est facile de remplacer accidentellement les tabulations par des espaces (ton éditeur peut le faire automatiquement), et
  2. il est difficile de repérer la différence entre les espaces et les tabulations.

Quand utiliser les here documents

  • Entrée multiligne : quand tu dois fournir plusieurs lignes de texte à une commande.
  • Fichiers de configuration : intégrer de petits extraits de configuration dans un script.
  • Génération de code : créer du code à la volée dans un script.
  • Interactions scriptées : simuler la saisie de l'utilisateur pour des programmes interactifs.
  • Éviter les fichiers externes : quand tu veux éviter de créer des fichiers temporaires.

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

Inconvénients possibles

  • Les documents intégrés volumineux peuvent rendre ton code plus difficile à lire. Il peut être préférable de déployer ton script avec la documentation dans des fichiers séparés.
  • Les here documents peuvent casser le flux du code. Tu peux te trouver dans une section de code profondément imbriquée au moment où tu veux transmettre du texte à un programme. L'indentation du here document peut sembler décalée par rapport au code qui l'entoure.

Les here strings

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.

Pourquoi utiliser les here strings ?

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 :

  • capturer la réponse JSON à une requête d'API REST (paginée),
  • fournir les données JSON à un programme jq pour analyser les résultats et écrire le tout dans un fichier, puis
  • fournir les données JSON à un autre programme jq pour déterminer l'URL de la requête suivante.
# 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.

Les here documents et here strings comme redirection

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

En résumé

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.

Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet