Aller au contenu
Administration Linux medium

Redirections avancées, here-doc et xargs

14 min de lecture

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

  • Créer du contenu textuel multiligne avec << EOF dans 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 comm et la process substitution
  • Transformer un flux en arguments avec xargs, -I {}, -n1 et -P
  • Protéger les noms de fichiers avec espaces grâce à -print0 | xargs -0
  • 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 :

Fenêtre de terminal
mkdir -p ~/Projets/lab-linux/exploiter/redirections-avancees
cd ~/Projets/lab-linux/exploiter/redirections-avancees

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.

Fenêtre de terminal
cat << 'EOF'
Serveur : web01
IP : 192.168.1.10
Rôle : nginx reverse proxy
EOF

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

Fenêtre de terminal
SERVEUR="web01"
IP="192.168.1.10"
cat << EOF
Rapport généré le $(date +%Y-%m-%d)
Hôte : $SERVEUR
Adresse : $IP
EOF

Sortie :

Rapport généré le 2026-04-09
Hôte : web01
Adresse : 192.168.1.10

Quand le marqueur n’est pas entre guillemets (<< EOF), le shell interprète $VAR et $(cmd).

Fenêtre de terminal
cat << 'EOF'
Pour accéder à $SERVEUR, tapez : ssh $USER@$IP
Expansion désactivée : $(date) ne sera pas remplacé
EOF

Sortie littérale — aucune variable n’est expansée. Utile pour générer des scripts ou du code contenant des variables shell.

Fenêtre de terminal
cat > /etc/nginx/conf.d/app.conf << 'EOF'
server {
listen 80;
server_name app.local;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
EOF

La combinaison cat > fichier << 'EOF' est la base de nombreux scripts de déploiement et d’infrastructure-as-code.

Pour indenter proprement un here-doc dans une fonction ou un bloc if :

Fenêtre de terminal
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).


Le here-doc n’est pas réservé à cat. Il peut alimenter n’importe quelle commande qui lit sur stdin :

Fenêtre de terminal
# Passer des requêtes SQL à mysql
mysql -u root -p ma_base << 'EOF'
SELECT user, host FROM mysql.user;
SHOW DATABASES;
EOF
Fenêtre de terminal
# Alimenter sed avec un here-doc
sed 's/prod/staging/' << 'EOF'
Serveur prod01
Base prod-db
Config : prod.conf
EOF
Fenêtre de terminal
# Transmettre une liste de paquets à xargs
xargs apt-get install -y << 'EOF'
curl
jq
tree
htop
EOF

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

Sans process substitution, comparer deux sorties requiert des fichiers temporaires :

Fenêtre de terminal
# Méthode classique — 3 étapes
ls /etc/*.conf | sort > /tmp/list_conf.txt
ls /var/log/*.conf 2>/dev/null | sort > /tmp/list_log_conf.txt
diff /tmp/list_conf.txt /tmp/list_log_conf.txt
rm /tmp/list_conf.txt /tmp/list_log_conf.txt

Avec process substitution — une ligne :

Fenêtre de terminal
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.

Fenêtre de terminal
# Comparer deux listes triées
diff <(sort liste1.txt) <(sort liste2.txt)

Sortie :

2d1
< bravo
4d2
< delta
5a4,5
> foxtrot
> golf
> hotel

comm compare deux fichiers supposés triés. La process substitution évite de pré-trier sur disque :

Fenêtre de terminal
# Lignes présentes dans liste1 mais pas dans liste2
comm -23 <(sort liste1.txt) <(sort liste2.txt)
OptionAffiche
-23Uniquement colonne 1 (liste1 seule)
-13Uniquement colonne 2 (liste2 seule)
-12Uniquement les lignes communes
Fenêtre de terminal
# Utilisateurs système avec UID ≥ 1000 qui ne sont pas connectés
comm -23 \
<(awk -F: '$3 >= 1000 {print $1}' /etc/passwd | sort) \
<(who | awk '{print $1}' | sort -u)
Fenêtre de terminal
# Compter les lignes d'erreur dans un log sans fichier temporaire
wc -l < <(grep "ERROR" /var/log/syslog 2>/dev/null)

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.

Fenêtre de terminal
# Compter les lignes de tous les fichiers .txt
ls *.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).

Fenêtre de terminal
# Afficher la taille de toutes les configs nginx
find /etc/nginx -name "*.conf" | xargs ls -lh

Par défaut, xargs ajoute l’argument à la fin. -I {} permet de le placer n’importe où dans la commande :

Fenêtre de terminal
# Copier des fichiers listés dans un fichier vers un dossier backup
cat liste1.txt | xargs -I {} cp {} backup/
Fenêtre de terminal
# Renommer en ajoutant une extension .bak
find /etc -name "*.conf" -maxdepth 1 | xargs -I {} cp {} {}.bak

Sans -n1, xargs regroupe les arguments pour minimiser le nombre d’appels. Avec -n1, chaque entrée déclenche un appel séparé :

Fenêtre de terminal
# Voir chaque fichier séparément
echo "liste1.txt liste2.txt" | xargs -n1 wc -l

Sortie :

5 liste1.txt
5 liste2.txt

Vs sans -n1 : wc -l liste1.txt liste2.txt (un seul appel avec total).

Fenêtre de terminal
# 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èle
cat urls.txt | xargs -P8 -I {} wget -q {}
Fenêtre de terminal
# Installer une liste de paquets définie dans le script
xargs apt-get install -y << 'EOF'
git
curl
jq
htop
tree
EOF
Fenêtre de terminal
# Copier une liste de fichiers avec une source explicite
cat << 'EOF' | xargs -I {} cp /etc/{} /tmp/backup/
passwd
group
hosts
hostname
EOF

Fenêtre de terminal
# ERREUR — espace avant EOF
cat << 'EOF'
contenu
EOF # ← ne ferme pas le here-doc !
EOF

Le marqueur de fermeture doit être seul, sans espace, en colonne 1 (sauf avec <<- qui tolère les tabs).

#!/bin/sh # ← ERREUR si on utilise <(...)
diff <(sort f1) <(sort f2) # Syntax error: unexpected "("

Solution : changer le shebang en #!/bin/bash.

Fenêtre de terminal
# Problème : "fichier avec espace.txt" devient 3 arguments
ls *.txt | xargs wc -l
# → wc: fichier: No such file or directory

Solution : find avec -print0 (séparateur null) et xargs -0 :

Fenêtre de terminal
find . -name "*.txt" -print0 | xargs -0 wc -l

Si le flux est vide, xargs appelle quand même la commande sans argument — ce qui peut être indésirable :

Fenêtre de terminal
# Sécuriser avec --no-run-if-empty (ou -r)
find . -name "*.bak" -print0 | xargs -0 -r rm

TechniqueSyntaxeUsage typique
Here-doc avec interpolation<< EOFGénérer des configs dans un script
Here-doc sans interpolation<< 'EOF'Générer du code ou des templates
Here-doc indenté<<- EOFLisibilité dans les fonctions
Process substitution<(cmd)diff, comm, comparaisons à la volée
xargs basiquecmd | xargs cmd2Appliquer une commande à une liste
xargs avec position... | xargs -I {} cmd {}Renommage, copie, transformation
xargs parallèle... | xargs -P4 cmdCompression, téléchargement en masse
Protéger les espacesfind -print0 | xargs -0Noms de fichiers avec espaces

  • << EOF interprè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.
  • xargs est plus robuste et plus efficace que for f in $(ls ...) pour traiter des listes.
  • Toujours utiliser -print0 | xargs -0 dè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.

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn