Retour au cours

redirections pipes

Objectifs

  • Comprendre les 3 flux standards : entrée, sortie, et erreur.
  • Rediriger la sortie d’une commande vers un fichier avec > et >>.
  • Isoler les messages d’erreur avec 2>.
  • Enchaîner des commandes pour créer des pipelines avec le pipe |.
  • Dupliquer une sortie avec tee.

Explications détaillées

Notions clés

Les 3 flux standards

Chaque commande que vous exécutez dispose de trois “canaux” de communication :

  1. Entrée standard (stdin, descripteur 0) : C’est là que la commande lit les données, par défaut le clavier.
  2. Sortie standard (stdout, descripteur 1) : C’est là que la commande écrit son résultat principal, par défaut le terminal.
  3. Erreur standard (stderr, descripteur 2) : C’est là que les messages d’erreur sont écrits, par défaut aussi le terminal.

Comprendre et maîtriser ces flux est la clé pour automatiser efficacement.

Redirection de la sortie (> et >>)

  • commande > fichier.txt : Redirige la sortie standard vers fichier.txt. Attention, le fichier est écrasé s’il existe déjà.
  • commande >> fichier.txt : Redirige la sortie standard et l’ajoute à la fin de fichier.txt sans l’écraser.

Redirection de l’erreur (2>)

  • commande_qui_echoue 2> erreurs.log : Redirige uniquement les messages d’erreur vers erreurs.log. La sortie standard (s’il y en a) s’affiche toujours dans le terminal.
  • Pour ignorer les erreurs : commande 2> /dev/null. /dev/null est un “trou noir” qui supprime tout ce qu’on lui envoie.

Redirection combinée (&> ou 2>&1)

  • commande &> tout.log : Redirige sortie standard ET erreur standard vers tout.log. C’est une syntaxe moderne et concise.
  • commande > tout.log 2>&1 : L’ancienne syntaxe, qui fait la même chose. Elle signifie “redirige la sortie standard vers le fichier, puis redirige l’erreur standard vers la même destination que la sortie standard”.

Le Pipe (|)

Le “pipe” (tuyau en anglais) est l’un des concepts les plus puissants du shell. Il connecte la sortie standard d’une commande à l’entrée standard de la commande suivante. Cela permet de créer des chaînes de traitement complexes.

commande1 | commande2 | commande3

tee : Voir et enregistrer en même temps

La commande tee est comme un T en plomberie. Elle lit depuis son entrée standard, l’envoie à la fois sur sa sortie standard (pour que vous la voyiez dans le terminal) ET dans un ou plusieurs fichiers.

longue_operation | tee resultat.log

Syntaxe / Usages

# Sauvegarder la liste des fichiers dans un fichier
ls -l > liste_fichiers.txt

# Ajouter la date actuelle à un journal
date >> journal.log

# Exécuter une commande potentiellement bruyante et ignorer les erreurs
find / -name "secret.txt" 2> /dev/null

# Journaliser la sortie complète (stdout + stderr) d'un script
./mon_script.sh &> script.log

# Compter le nombre de fichiers dans le dossier courant
ls | wc -l

# Afficher les 5 plus gros fichiers et sauvegarder la liste complète
du -h * | sort -rh | tee tous_fichiers.txt | head -n 5

Exemples

# 1. Créer un fichier avec la liste des processus en cours
ps aux > processus.txt

# 2. Chercher combien de processus 'bash' tournent
# On utilise la sortie de 'ps' comme entrée de 'grep'
ps aux | grep "bash"

# 3. Compter le nombre de lignes dans la sortie précédente
ps aux | grep "bash" | wc -l

# 4. Sauvegarder la liste des utilisateurs connectés tout en l'affichant
who | tee utilisateurs.txt

Bonnes pratiques

  • Utilisez set -o pipefail dans vos scripts. Par défaut, si une commande au milieu d’un pipe échoue, le script ne s’arrête pas. Cette option corrige ce comportement.
  • Redirigez toujours les erreurs dans les scripts automatisés (ex: cron). Soit vers un fichier de log, soit vers /dev/null si elles sont attendues et sans importance.
  • Quand vous écrivez dans un fichier, décidez consciemment si vous devez écraser (>) ou ajouter (>>).

Pièges courants

  • Écrasement accidentel avec > : C’est l’erreur la plus fréquente. Une seconde d’inattention et votre fichier de configuration est remplacé par la sortie d’une commande.
  • Le pipe ne transmet que stdout : Les messages d’erreur ne sont pas passés à la commande suivante dans le pipe. Si vous voulez les traiter aussi, il faut les rediriger vers stdout avec 2>&1. Ex: commande_complete 2>&1 | une_autre_commande.
  • Commandes dans un subshell : Chaque partie d’un pipe s’exécute dans son propre “subshell”. Cela signifie qu’une variable modifiée dans une partie du pipe ne sera pas visible dans la suivante (un concept plus avancé).

Exercices

  1. Journalisation simple :

    • Écrivez une commande qui liste le contenu détaillé (ls -l) de votre dossier personnel (~) et sauvegarde le résultat dans un fichier nommé contenu_home.txt.
    • Ensuite, ajoutez la date et l’heure actuelles à la fin de ce même fichier.
  2. Chaîne de commandes :

    • Écrivez une seule ligne de commande qui :
      1. Affiche l’historique de vos commandes (history).
      2. Filtre pour ne garder que les lignes contenant ls.
      3. Compte le nombre de fois où vous avez utilisé ls.
  3. Gestion des erreurs :

    • Essayez de lister un dossier qui n’existe pas, par exemple ls /dossier_inexistant.
    • Maintenant, exécutez la même commande mais redirigez le message d’erreur (et seulement lui) dans un fichier erreurs.log.
    • Vérifiez le contenu de erreurs.log avec cat.