🎯 Ce que tu sauras à la fin
Les flux
stdin, stdout, stderr et leurs numéros.
Rediriger
>, >>, 2>, /dev/null…
Combiner
Construire des pipelines avec |.
Filtrer
grep, sort, uniq, cut, sed, awk.
Les trois flux standard
Tout programme démarre avec trois canaux ouverts, numérotés :
| N° | Nom | Rôle | Par défaut |
|---|---|---|---|
0 | stdin | Entrée standard : ce que le programme lit | Le clavier |
1 | stdout | Sortie standard : les résultats | L'écran |
2 | stderr | Sortie d'erreur : les messages d'erreur | L'écran |
Les redirections
| Syntaxe | Effet |
|---|---|
cmd > fichier | stdout dans un fichier, écrasé s'il existe |
cmd >> fichier | stdout ajouté à la fin du fichier |
cmd 2> erreurs.txt | stderr dans un fichier |
cmd > tout.txt 2>&1 | stdout dans le fichier, puis stderr envoyé au même endroit que stdout |
cmd &> tout.txt | Raccourci Bash pour la ligne précédente |
cmd < fichier | stdin lu depuis un fichier |
cmd 2> /dev/null | Faire disparaître les erreurs dans le « trou noir » |
user@ubuntu:~$ ls /etc /nexistepas > sortie.txt ls: impossible d'accéder à '/nexistepas': Aucun fichier ou dossier de ce nom # stderr reste à l'écran user@ubuntu:~$ ls /etc /nexistepas > sortie.txt 2> erreurs.txt # chacun dans son fichier user@ubuntu:~$ find / -name "*.conf" 2> /dev/null # sans les centaines de « Permission non accordée » user@ubuntu:~$ echo "$(date) : sauvegarde OK" >> journal.txt # tenir un journal user@ubuntu:~$ wc -l < /etc/passwd # wc lit stdin : pas de nom de fichier affiché 37
> écrase sans prévenir
sort notes.txt > notes.txt vide le fichier : le shell le tronque avant même que sort ne le lise.
On écrit toujours dans un autre fichier, puis on renomme. Pour se protéger, set -o noclobber fait refuser à Bash l'écrasement avec >.
2>&1
2>&1 signifie « envoie stderr là où va stdout en ce moment ». Dans cmd > f 2>&1, stdout va déjà dans f : tout y va.
Dans cmd 2>&1 > f, stderr a été branché sur l'écran avant que stdout ne soit redirigé : les erreurs restent à l'écran.
Écrire plusieurs lignes : le « here-document »
user@ubuntu:~$ cat > courses.txt << 'FIN' > pommes > pain > café > FIN user@ubuntu:~$ cat courses.txt pommes pain café
Tout ce qui est tapé jusqu'au mot FIN (seul sur sa ligne) est envoyé sur stdin. Très utilisé dans les scripts pour créer des fichiers de configuration.
Le pipe : l'art de combiner
Le pipe | (AltGr + 6 sur un clavier AZERTY) branche le stdout d'une commande sur le stdin de la suivante.
Les données coulent d'un programme à l'autre, sans fichier intermédiaire, et tous les programmes tournent en même temps.
Le pipe a été proposé par Doug McIlroy aux Bell Labs et ajouté à Unix par Ken Thompson en 1973, en une nuit selon la légende. McIlroy a résumé la philosophie qui en découle : « Écrivez des programmes qui font une seule chose et la font bien. Écrivez des programmes qui travaillent ensemble. Écrivez des programmes qui manipulent des flux de texte. »
Préparer un fichier d'exemple pour tout le module
Pour s'entraîner, voici un petit journal de serveur web. Copie ce bloc dans ton terminal : il crée ~/labo/acces.log.
user@ubuntu:~$ mkdir -p ~/labo && cat > ~/labo/acces.log << 'FIN' 192.168.1.10 - - [23/Oct/2026:10:01:12] "GET /index.html" 200 5120 192.168.1.22 - - [23/Oct/2026:10:01:15] "GET /contact.html" 200 2048 10.0.0.5 - - [23/Oct/2026:10:02:01] "GET /admin" 403 512 192.168.1.10 - - [23/Oct/2026:10:02:30] "GET /images/logo.png" 200 15360 192.168.1.10 - - [23/Oct/2026:10:03:12] "GET /blog.html" 200 8192 10.0.0.5 - - [23/Oct/2026:10:03:45] "GET /admin" 403 512 172.16.0.8 - - [23/Oct/2026:10:04:02] "GET /index.html" 200 5120 192.168.1.22 - - [23/Oct/2026:10:04:59] "GET /page-perdue.html" 404 256 10.0.0.5 - - [23/Oct/2026:10:05:30] "POST /login" 401 128 192.168.1.10 - - [23/Oct/2026:10:06:10] "GET /index.html" 200 5120 172.16.0.8 - - [23/Oct/2026:10:06:44] "GET /blog.html" 200 8192 10.0.0.5 - - [23/Oct/2026:10:07:02] "POST /login" 401 128 FIN
user@ubuntu:~/labo$ cut -d' ' -f1 acces.log | sort | uniq -c | sort -nr | head -3 4 192.168.1.10 4 10.0.0.5 2 192.168.1.22
Ne tape jamais un long pipeline d'un coup. Ajoute une commande à la fois, regarde le résultat, puis rappelle la ligne avec ↑ et ajoute le maillon suivant. C'est comme ça que les pros procèdent.
La boîte à filtres
grep : garder les lignes qui correspondent
| Option | Effet | Exemple |
|---|---|---|
| Lignes contenant le motif | grep 404 acces.log | |
-i | Ignorer majuscules/minuscules | grep -i error /var/log/syslog |
-v | Inverser : lignes qui ne correspondent pas | grep -v '^#' fichier.conf |
-c | Compter les lignes | grep -c 403 acces.log |
-n | Afficher les numéros de ligne | grep -n root /etc/passwd |
-r | Chercher dans tous les fichiers d'un dossier | grep -r "Port" /etc/ssh/ |
-w | Mot entier seulement | grep -w log fichier |
-E | Expressions régulières étendues | grep -E '40[134]' acces.log |
Les expressions régulières (^ début de ligne, $ fin, . n'importe quel caractère…) seront approfondies au module 06.
Trier, dédoublonner, compter, découper
| Commande | Rôle | Options clés |
|---|---|---|
sort | Trier les lignes | -n numérique · -r inverse · -h tailles (2K, 1G) · -k2 sur la 2e colonne · -t: séparateur · -u sans doublons |
uniq | Fusionner les lignes identiques consécutives | -c compter · -d seulement les doublons. Toujours après sort ! |
wc | Compter | -l lignes · -w mots · -c octets |
cut | Extraire des colonnes | -d: séparateur · -f1,3 champs · -c1-10 caractères |
tr | Remplacer ou supprimer des caractères | tr a-z A-Z majuscules · tr -d '\r' supprimer · tr -s ' ' compresser |
head / tail | Garder le début / la fin | -n 5 |
tee | Écrire dans un fichier et laisser passer | -a ajouter. Ex. cmd | tee resultat.txt |
user@ubuntu:~$ cut -d: -f1,7 /etc/passwd | head -3 # identifiant et shell root:/bin/bash daemon:/usr/sbin/nologin bin:/usr/sbin/nologin user@ubuntu:~$ cut -d: -f7 /etc/passwd | sort | uniq -c # combien de comptes par shell ? 1 /bin/false 2 /bin/bash 1 /bin/sync 33 /usr/sbin/nologin user@ubuntu:~$ du -sh /var/* 2>/dev/null | sort -hr | head -3 # les plus gros dossiers de /var 2,1G /var/lib 410M /var/cache 95M /var/log user@ubuntu:~$ echo "bonjour linux" | tr a-z A-Z BONJOUR LINUX
Aperçu de sed et awk
Deux outils plus puissants, presque des langages à eux seuls. L'essentiel suffit pour 90 % des usages.
sed : rechercher et remplacer dans un flux
user@ubuntu:~/labo$ sed 's/GET/LECTURE/' acces.log | head -2 # s/ancien/nouveau/ : 1re occurrence par ligne 192.168.1.10 - - [23/Oct/2026:10:01:12] "LECTURE /index.html" 200 5120 192.168.1.22 - - [23/Oct/2026:10:01:15] "LECTURE /contact.html" 200 2048 user@ubuntu:~/labo$ sed 's/a/A/g' courses.txt # g : toutes les occurrences user@ubuntu:~/labo$ sed -n '3,5p' acces.log # afficher les lignes 3 à 5 user@ubuntu:~/labo$ sed '/403/d' acces.log # supprimer les lignes contenant 403 user@ubuntu:~/labo$ sed -i.bak 's/pain/baguette/' courses.txt # -i : modifie le fichier (copie .bak)
awk : travailler par colonnes
awk découpe chaque ligne en champs $1, $2… (séparés par des espaces, ou par ce que précise -F) et permet des conditions et des calculs.
Dans notre journal, la méthode "GET forme un champ à elle seule : l'IP est $1, la page $6, le code HTTP $7 et la taille $8.
user@ubuntu:~/labo$ awk '{print $1, $7}' acces.log | head -2 # IP et code HTTP 192.168.1.10 200 192.168.1.22 200 user@ubuntu:~/labo$ awk '$7 >= 400' acces.log | wc -l # nombre de requêtes en erreur 5 user@ubuntu:~/labo$ awk '{total += $8} END {print total " octets"}' acces.log 50688 octets user@ubuntu:~$ awk -F: '$3 >= 1000 {print $1}' /etc/passwd # les comptes humains user nobody
Enchaîner des commandes : ; && || et $( )
| Syntaxe | Signification | Exemple |
|---|---|---|
a ; b | b s'exécute après a, quoi qu'il arrive | cd /tmp ; ls |
a && b | b seulement si a a réussi (code 0) | sudo apt update && sudo apt upgrade |
a || b | b seulement si a a échoué | ping -c1 serveur || echo "injoignable" |
$(commande) | Remplacé par la sortie de la commande | echo "Noyau : $(uname -r)" |
user@ubuntu:~$ mkdir sauvegarde && cp -r labo sauvegarde/ && echo "OK" || echo "ÉCHEC" OK user@ubuntu:~$ cp labo/acces.log "acces-$(date +%F).log" && ls acces-* acces-2026-10-23.log
Glossaire du module
- stdin / stdout / stderr
- Entrée standard (0), sortie standard (1), sortie d'erreur (2).
- Redirection
- Changer la destination ou la source d'un flux :
>,>>,2>,<. - /dev/null
- Fichier spécial qui avale tout ce qu'on lui envoie.
- Here-document
- Bloc de texte envoyé sur stdin avec
<< MOT. - Pipe
|: relie le stdout d'une commande au stdin de la suivante.- Pipeline
- Chaîne de commandes reliées par des pipes.
- Filtre
- Programme qui lit stdin, transforme, et écrit sur stdout.
- grep
- Garde les lignes qui correspondent à un motif.
- sed
- Éditeur de flux : remplacements, suppressions de lignes.
- awk
- Traitement par colonnes, conditions et calculs.
&&/||- Exécuter la suite si succès / si échec.
- Substitution de commande
$(cmd)est remplacé par la sortie decmd.
🧠 Quiz : as-tu tout retenu ?
> et >> ?> remplace le contenu, >> l'allonge.> /dev/null masquerait au contraire les résultats et garderait les erreurs.sort avant uniq -c ?grep -v '^#' fichier.conf ?-v inverse la sélection ; ^# = « commence par # ». Le fichier n'est pas modifié.awk '{print $3}', que représente $3 ?$3.sudo apt update && sudo apt upgrade : quand upgrade est-il lancé ?&& enchaîne en cas de succès (code de retour 0).notes.txt après sort notes.txt > notes.txt ?notes.txt pour la redirection avant que sort ne le lise.🚀 Mission pratique
À faire dans la machine virtuelle
Coche chaque étape une fois faite : sa correction s'affiche juste en dessous.
- ✅ Correction
$ wc -l ~/labo/acces.log 12 /home/user/labo/acces.log
Si le compte n'est pas bon, vérifie que
FINétait bien seul sur sa dernière ligne. - ✅ Correction
$ cd ~/labo $ ls /etc > liste.txt $ ls /var >> liste.txt $ wc -l liste.txt 215 liste.txt
- ✅ Correction
$ ls /etc /nexistepas > ok.txt 2> ko.txt $ cat ko.txt ls: impossible d'accéder à '/nexistepas': Aucun fichier ou dossier de ce nom $ ls /etc /nexistepas > tout.txt 2>&1 $ head -1 tout.txt ls: impossible d'accéder à '/nexistepas': Aucun fichier ou dossier de ce nom
- ✅ Correction
$ find /etc -name "*.conf" 2> /dev/null | wc -l 118
Le nombre exact varie. Sans
2> /dev/null, les dossiers interdits produisent des messages « Permission non accordée ». - ✅ Correction
$ grep ' 403 ' acces.log 10.0.0.5 - - [23/Oct/2026:10:02:01] "GET /admin" 403 512 10.0.0.5 - - [23/Oct/2026:10:03:45] "GET /admin" 403 512 $ grep -c ' 403 ' acces.log 2
Les espaces autour de
403évitent de trouver ce nombre ailleurs dans la ligne (une taille, une heure). - ✅ Correction
$ cut -d' ' -f1 acces.log | sort | uniq -c | sort -nr | head -3 4 192.168.1.10 4 10.0.0.5 2 192.168.1.22
Il y a deux égalités :
192.168.1.10et10.0.0.5(4 requêtes chacune), puis192.168.1.22et172.16.0.8(2 chacune). L'ordre des ex æquo peut varier. - ✅ Correction
$ awk '{print $6}' acces.log | sort -u /admin" /blog.html" /contact.html" /images/logo.png" /index.html" /login" /page-perdue.html" $ awk '{print $6}' acces.log | tr -d '"' | sort -u # sans le guillemet
- ✅ Correction
$ awk '{total += $8} END {print total}' acces.log 50688 $ awk '$7 >= 400' acces.log | wc -l 5
- ✅ Correction
$ sed 's/GET/LECTURE/' acces.log > acces-fr.log $ grep -c LECTURE acces-fr.log 10 $ grep -c GET acces.log 10
- ✅ Correction
$ cut -d' ' -f1 acces.log | sort | uniq -c | sort -nr | tee "rapport-$(date +%F).txt" && echo "Rapport prêt" 4 192.168.1.10 4 10.0.0.5 2 192.168.1.22 1 ... Rapport prêt
💬 Questions fréquentes
Les questions qui reviennent le plus souvent sur ce module, avec leurs réponses.
Comment taper le caractère | sur un clavier AZERTY ?
AltGr + 6 (la touche du tiret). Sur un Mac : Alt + Maj + L. Pour les autres symboles utiles :
~ = AltGr + 2 puis Espace, { } = AltGr + 4 / +, [ ] = AltGr + 5 / °.
sudo echo "texte" > /etc/fichier donne « Permission non accordée »
La redirection > est faite par ton shell, sans droits root ; seul echo tourne avec sudo. La solution :
echo "texte" | sudo tee /etc/fichier (ou sudo tee -a pour ajouter). Ici, c'est tee qui écrit, avec les droits de root.
Mon pipeline ne renvoie rien
Démonte-le : exécute la première commande seule, puis ajoute les maillons un par un avec ↑. Le coupable est souvent un séparateur
mal choisi dans cut (espace contre tabulation) ou un grep sensible aux majuscules (essaie -i).