Le shell fait bien plus que rediriger > et <. Le here-doc permet d’intégrer un bloc de texte directement dans un script sans fichier temporaire. La process substitution traite la sortie d’une commande comme si c’était un fichier. Et xargs transforme n’importe quel flux en arguments d’une commande — avec ou sans parallélisme.
Ce sont des techniques directement ciblées par l’objectif LFCS (“Create and Edit Text Files”, “Use Input/Output Redirection”).
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Créer du contenu textuel multiligne avec
<< EOFdans des scripts - Contrôler l’interpolation des variables dans un here-doc
- Comparer deux sorties de commandes avec
diff <(...)sans fichier temporaire - Extraire les lignes communes ou uniques avec
commet la process substitution - Transformer un flux en arguments avec
xargs,-I {},-n1et-P - Protéger les noms de fichiers avec espaces grâce à
-print0 | xargs -0
Prérequis
Section intitulée « Prérequis »- Maîtrise du shell bash (redirections
>,<, pipes|) - Bases des commandes de traitement de texte (
grep,sort,diff)
Lab A — Shell local : tous les exemples s’exécutent directement dans votre terminal. Créez le dossier de travail :
mkdir -p ~/Projets/lab-linux/exploiter/redirections-avanceescd ~/Projets/lab-linux/exploiter/redirections-avanceesHere-doc : un bloc de texte sans fichier
Section intitulée « Here-doc : un bloc de texte sans fichier »Un here-doc permet d’injecter un bloc de texte multiligne directement dans une commande ou un script — sans créer de fichier intermédiaire.
Syntaxe de base
Section intitulée « Syntaxe de base »cat << 'EOF'Serveur : web01IP : 192.168.1.10Rôle : nginx reverse proxyEOFLe marqueur peut s’appeler EOF, END, HEREDOC ou n’importe quoi d’autre — c’est la convention EOF qui est universelle. La ligne de fermeture doit être seule sur sa ligne, sans espace avant.
Avec interpolation de variables
Section intitulée « Avec interpolation de variables »SERVEUR="web01"IP="192.168.1.10"
cat << EOFRapport généré le $(date +%Y-%m-%d)Hôte : $SERVEURAdresse : $IPEOFSortie :
Rapport généré le 2026-04-09Hôte : web01Adresse : 192.168.1.10Quand le marqueur n’est pas entre guillemets (<< EOF), le shell interprète $VAR et $(cmd).
Sans interpolation — marqueur entre guillemets
Section intitulée « Sans interpolation — marqueur entre guillemets »cat << 'EOF'Pour accéder à $SERVEUR, tapez : ssh $USER@$IPExpansion désactivée : $(date) ne sera pas remplacéEOFSortie littérale — aucune variable n’est expansée. Utile pour générer des scripts ou du code contenant des variables shell.
Créer un fichier directement
Section intitulée « Créer un fichier directement »cat > /etc/nginx/conf.d/app.conf << 'EOF'server { listen 80; server_name app.local; location / { proxy_pass http://127.0.0.1:3000; }}EOFLa combinaison cat > fichier << 'EOF' est la base de nombreux scripts de déploiement et d’infrastructure-as-code.
Here-doc indenté avec <<-
Section intitulée « Here-doc indenté avec <<- »Pour indenter proprement un here-doc dans une fonction ou un bloc if :
generer_config() { local host=$1 cat <<-EOF Hôte : $host Date : $(date +%Y-%m-%d) Status : actif EOF}
generer_config "web01"<<- supprime les tabulations en début de ligne (pas les espaces — utiliser des vraies tabs dans l’éditeur).
Alimenter des commandes avec un here-doc
Section intitulée « Alimenter des commandes avec un here-doc »Le here-doc n’est pas réservé à cat. Il peut alimenter n’importe quelle commande qui lit sur stdin :
# Passer des requêtes SQL à mysqlmysql -u root -p ma_base << 'EOF'SELECT user, host FROM mysql.user;SHOW DATABASES;EOF# Alimenter sed avec un here-docsed 's/prod/staging/' << 'EOF'Serveur prod01Base prod-dbConfig : prod.confEOF# Transmettre une liste de paquets à xargsxargs apt-get install -y << 'EOF'curljqtreehtopEOFProcess substitution : <(cmd) traite une sortie comme un fichier
Section intitulée « Process substitution : <(cmd) traite une sortie comme un fichier »La process substitution permet de passer la sortie d’une commande là où un outil attend un fichier. Bash crée un descripteur de fichier virtuel (/dev/fd/N) à la volée.
diff entre deux sorties de commandes
Section intitulée « diff entre deux sorties de commandes »Sans process substitution, comparer deux sorties requiert des fichiers temporaires :
# Méthode classique — 3 étapesls /etc/*.conf | sort > /tmp/list_conf.txtls /var/log/*.conf 2>/dev/null | sort > /tmp/list_log_conf.txtdiff /tmp/list_conf.txt /tmp/list_log_conf.txtrm /tmp/list_conf.txt /tmp/list_log_conf.txtAvec process substitution — une ligne :
diff <(ls /etc/*.conf | sort) <(ls /var/log/*.conf 2>/dev/null | sort)Cas d’usage typique : comparer deux fichiers dans un ordre trié que vous ne voulez pas enregistrer.
# Comparer deux listes triéesdiff <(sort liste1.txt) <(sort liste2.txt)Sortie :
2d1< bravo4d2< delta5a4,5> foxtrot> golf> hotelcomm avec process substitution
Section intitulée « comm avec process substitution »comm compare deux fichiers supposés triés. La process substitution évite de pré-trier sur disque :
# Lignes présentes dans liste1 mais pas dans liste2comm -23 <(sort liste1.txt) <(sort liste2.txt)| Option | Affiche |
|---|---|
-23 | Uniquement colonne 1 (liste1 seule) |
-13 | Uniquement colonne 2 (liste2 seule) |
-12 | Uniquement les lignes communes |
# Utilisateurs système avec UID ≥ 1000 qui ne sont pas connectéscomm -23 \ <(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sort) \ <(who | awk '{print $1}' | sort -u)wc sur une sortie filtrée
Section intitulée « wc sur une sortie filtrée »# Compter les lignes d'erreur dans un log sans fichier temporairewc -l < <(grep "ERROR" /var/log/syslog 2>/dev/null)xargs : transformer un flux en arguments
Section intitulée « xargs : transformer un flux en arguments »xargs lit stdin ligne par ligne (ou mot par mot) et passe chaque entrée comme argument à une commande. C’est l’alternative aux boucles for f in $(ls ...) — plus robuste et plus efficace.
Usage basique
Section intitulée « Usage basique »# Compter les lignes de tous les fichiers .txtls *.txt | xargs wc -lÉquivaut à wc -l liste1.txt liste2.txt mais fonctionne même avec 1000 fichiers (la limite d’arguments shell ne s’applique pas).
# Afficher la taille de toutes les configs nginxfind /etc/nginx -name "*.conf" | xargs ls -lh-I {} : placer l’argument à un endroit précis
Section intitulée « -I {} : placer l’argument à un endroit précis »Par défaut, xargs ajoute l’argument à la fin. -I {} permet de le placer n’importe où dans la commande :
# Copier des fichiers listés dans un fichier vers un dossier backupcat liste1.txt | xargs -I {} cp {} backup/# Renommer en ajoutant une extension .bakfind /etc -name "*.conf" -maxdepth 1 | xargs -I {} cp {} {}.bak-n1 : un appel par argument
Section intitulée « -n1 : un appel par argument »Sans -n1, xargs regroupe les arguments pour minimiser le nombre d’appels. Avec -n1, chaque entrée déclenche un appel séparé :
# Voir chaque fichier séparémentecho "liste1.txt liste2.txt" | xargs -n1 wc -lSortie :
5 liste1.txt5 liste2.txtVs sans -n1 : wc -l liste1.txt liste2.txt (un seul appel avec total).
-P : traitement parallèle
Section intitulée « -P : traitement parallèle »# Compresser tous les logs en parallèle (4 processus simultanés)find /var/log -name "*.log" | xargs -P4 gzip
# Télécharger une liste d'URLs en parallèlecat urls.txt | xargs -P8 -I {} wget -q {}Here-doc + xargs : la combinaison la plus lisible
Section intitulée « Here-doc + xargs : la combinaison la plus lisible »# Installer une liste de paquets définie dans le scriptxargs apt-get install -y << 'EOF'gitcurljqhtoptreeEOF# Copier une liste de fichiers avec une source explicitecat << 'EOF' | xargs -I {} cp /etc/{} /tmp/backup/passwdgrouphostshostnameEOFPièges courants
Section intitulée « Pièges courants »Here-doc : fermeture sur une ligne seule
Section intitulée « Here-doc : fermeture sur une ligne seule »# ERREUR — espace avant EOFcat << 'EOF'contenu EOF # ← ne ferme pas le here-doc !EOFLe marqueur de fermeture doit être seul, sans espace, en colonne 1 (sauf avec <<- qui tolère les tabs).
Process substitution : bash requis
Section intitulée « Process substitution : bash requis »#!/bin/sh # ← ERREUR si on utilise <(...)diff <(sort f1) <(sort f2) # Syntax error: unexpected "("Solution : changer le shebang en #!/bin/bash.
xargs et noms avec espaces
Section intitulée « xargs et noms avec espaces »# Problème : "fichier avec espace.txt" devient 3 argumentsls *.txt | xargs wc -l# → wc: fichier: No such file or directorySolution : find avec -print0 (séparateur null) et xargs -0 :
find . -name "*.txt" -print0 | xargs -0 wc -lxargs : rien à traiter
Section intitulée « xargs : rien à traiter »Si le flux est vide, xargs appelle quand même la commande sans argument — ce qui peut être indésirable :
# Sécuriser avec --no-run-if-empty (ou -r)find . -name "*.bak" -print0 | xargs -0 -r rmTableau récapitulatif
Section intitulée « Tableau récapitulatif »| Technique | Syntaxe | Usage typique |
|---|---|---|
| Here-doc avec interpolation | << EOF | Générer des configs dans un script |
| Here-doc sans interpolation | << 'EOF' | Générer du code ou des templates |
| Here-doc indenté | <<- EOF | Lisibilité dans les fonctions |
| Process substitution | <(cmd) | diff, comm, comparaisons à la volée |
| xargs basique | cmd | xargs cmd2 | Appliquer une commande à une liste |
| xargs avec position | ... | xargs -I {} cmd {} | Renommage, copie, transformation |
| xargs parallèle | ... | xargs -P4 cmd | Compression, téléchargement en masse |
| Protéger les espaces | find -print0 | xargs -0 | Noms de fichiers avec espaces |
À retenir
Section intitulée « À retenir »<< EOFinterprète les variables ;<< 'EOF'ne le fait pas — le choix est explicite, pas accidentel.- La process substitution
<(cmd)évite les fichiers temporaires et rend les scripts plus lisibles. xargsest plus robuste et plus efficace quefor f in $(ls ...)pour traiter des listes.- Toujours utiliser
-print0 | xargs -0dès que des noms de fichiers peuvent contenir des espaces. - La process substitution ne fonctionne qu’avec
bash— vérifier le shebang dans les scripts.