Objectifs
- Fournir du texte sur plusieurs lignes à une commande en utilisant les “here documents” (
<<). - Passer une simple chaîne de caractères à l’entrée d’une commande avec les “here strings” (
<<<). - Comprendre le concept de descripteur de fichier (au-delà de stdin, stdout, stderr).
- Apercevoir des concepts très avancés comme les co-processus (
coproc).
Explications détaillées
Notions clés
Cette leçon couvre des techniques d’entrée/sortie (I/O) qui, une fois maîtrisées, rendent vos scripts beaucoup plus propres et plus puissants.
Here Documents (<<)
Un “here document” (souvent abrégé en “heredoc”) est une manière de rediriger un bloc de texte, écrit directement dans votre script, vers l’entrée standard d’une commande. C’est extrêmement utile pour inclure des messages multi-lignes, des fichiers de configuration, ou des requêtes SQL.
Syntaxe : commande << DELIMITEUR
Le bloc de texte commence à la ligne suivante et se termine lorsque le DELIMITEUR est rencontré, seul, en début de ligne. EOF (End Of File) est une convention populaire pour le délimiteur, mais vous pouvez utiliser ce que vous voulez.
<<- DELIMITEUR: Le-permet d’ignorer les tabulations au début de chaque ligne du heredoc, ce qui est pratique pour indenter votre code.
Par défaut, les variables ($VAR) et les substitutions de commande ($(cmd)) sont interprétées dans un heredoc. Pour un comportement littéral, mettez le délimiteur entre guillemets : << 'EOF'.
Here Strings (<<<)
Un “here string” est une version simplifiée du heredoc pour une seule chaîne de caractères. Il est plus efficace et plus lisible que echo "ma chaîne" | commande.
Syntaxe : commande <<< "ma chaîne"
Descripteurs de Fichiers (avancé)
Vous connaissez déjà les descripteurs 0, 1 et 2 (stdin, stdout, stderr). Bash vous permet d’en ouvrir d’autres (de 3 à 9) pour des redirections complexes.
exec 3> mon_log.txt: Ouvre le descripteur 3 en écriture versmon_log.txt.echo "Message de debug" >&3: Écrit sur ce descripteur.exec 3>&-: Ferme le descripteur 3. C’est un usage avancé, souvent utilisé pour séparer la sortie d’un script de ses logs de debug.
Co-processus (coproc) (très avancé)
coproc lance une commande en arrière-plan et crée des pipes pour communiquer avec elle de manière asynchrone. C’est très rare et réservé à des besoins très spécifiques d’interaction avec un processus persistant. Ce concept est mentionné ici pour information.
Syntaxe / Usages
# Envoyer un message multi-lignes à la commande 'cat'
cat << EOF
Ceci est la première ligne.
Ceci est la seconde.
L'indentation est préservée.
Votre utilisateur est : $USER.
EOF
# Utiliser un here string pour fournir une entrée à 'wc'
wc -w <<< "compter le nombre de mots"
# -> 4
# Redirection vers un descripteur de fichier personnalisé
exec 3> debug.log
echo "Début du script" >&3
# ...
echo "Fin du script" >&3
exec 3>&-
Exemples
# 1. Créer un fichier de configuration à la volée
# Le délimiteur 'EOF' est cité pour que $USER ne soit pas interprété
sudo tee /etc/myapp.conf > /dev/null << 'EOF'
# Configuration de Mon App
user = $USER
port = 8080
EOF
# 2. Passer une requête SQL à un client de base de données
# Les variables Bash sont interprétées, ce qui permet de dynamiser la requête
TABLE_NOM="utilisateurs"
psql -U postgres ma_base << EOF
SELECT COUNT(*)
FROM ${TABLE_NOM}
WHERE inscription_date >= '2025-01-01';
EOF
# 3. Comparer une variable à un texte multi-lignes
# (Usage avancé de la substitution de processus et de here string)
# diff <(echo "$MA_VARIABLE") <(cat << 'EOF'
# Contenu attendu
# sur plusieurs lignes.
# EOF
# )
Bonnes pratiques
- Utilisez les heredocs pour tout texte multi-lignes que vous devez passer à une commande. C’est plus lisible et moins sujet aux erreurs que de multiples
echo. - Utilisez les here strings (
<<<) pour passer une simple variable ou une chaîne courte à l’entrée d’une commande. C’est plus propre et plus efficace qu’unecho | .... - Quand vous utilisez un heredoc, décidez si vous avez besoin de l’expansion des variables. Si ce n’est pas le cas, citez le délimiteur (
<< 'EOF') pour plus de sécurité.
Pièges courants
- Le délimiteur de fin d’un heredoc : Il doit être absolument seul sur sa ligne, sans aucun espace avant ou après.
- Expansion non désirée : Oublier de citer le délimiteur peut conduire à l’interprétation de
$ou``dans votre bloc de texte, ce qui peut ne pas être le comportement souhaité.
Exercices
-
Bannière de bienvenue :
- Écrivez un script qui utilise un heredoc pour afficher une bannière de bienvenue sur plusieurs lignes.
- La bannière doit inclure le nom de l’utilisateur (
$USER) et la machine ($HOSTNAME).
-
Comptage de mots rapide :
- Définissez une variable contenant une phrase de votre choix.
- Utilisez un here string (
<<<) et la commandewc -wpour compter le nombre de mots dans cette variable.
-
Script SQL dynamique :
- Créez un script qui prend un nom de table en argument (
$1). - Utilisez un heredoc pour afficher (avec
echo) une requêteSELECT * FROM [nom_de_la_table] LIMIT 10;où le nom de la table est dynamique. - Exemple :
./mon_script.sh clientsdoit afficherSELECT * FROM clients LIMIT 10;.
- Créez un script qui prend un nom de table en argument (