Le système Linux#

Hide code cell source

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
import seaborn as sns

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)

Aux origines : Unix, GNU et Linux#

L’histoire de Linux est indissociable de celle d’Unix, le système d’exploitation qui a révolutionné l’informatique dans les années 1970 et dont les idées fondatrices continuent de gouverner les systèmes modernes. Pour comprendre pourquoi Linux est ce qu’il est aujourd’hui — une architecture modulaire, une philosophie « tout est fichier », une conception autour du shell et des petits programmes qui font une seule chose bien — il faut remonter aux Laboratoires Bell d’AT&T, dans le New Jersey de 1969.

Unix (Bell Labs, 1969)#

En 1969, Ken Thompson, Dennis Ritchie et quelques collègues des Bell Labs commencèrent à écrire un nouveau système d’exploitation sur un mini-ordinateur PDP-7 inutilisé. Ce projet, qu’ils appelèrent Unix, était une réaction à la lourdeur du projet Multics (Multiplexed Information and Computing Service), auquel AT&T venait de se retirer. Thompson et Ritchie voulaient un système simple, élégant et interactif. En 1972-1973, Dennis Ritchie inventa le langage C spécifiquement pour réécrire Unix, ce qui constitua une décision révolutionnaire : Unix fut le premier système d’exploitation portable, pouvant être transplanté sur des architectures matérielles différentes simplement en recompilant son code source.

Unix introduisit plusieurs concepts qui structurent encore nos systèmes actuels : la hiérarchie de répertoires, les permissions par utilisateur et groupe, les redirections d’entrées-sorties (>, <, |), et surtout la philosophie Unix formulée par Doug McIlroy : écrire des programmes qui ne font qu’une seule chose, mais qui la font bien, et qui coopèrent entre eux via des flux de texte standard. Cette philosophie est la matrice du shell Bash et de tous les outils que nous étudierons dans ce livre.

À partir de 1973, AT&T distribua Unix aux universités à faible coût, notamment à l’Université de Californie à Berkeley, qui développa sa propre variante : BSD (Berkeley Software Distribution). Cette branche donna naissance à FreeBSD, OpenBSD, NetBSD et, indirectement, à macOS (qui repose sur Darwin, un dérivé de BSD).

Le projet GNU (Stallman, 1983)#

En 1983, Richard Stallman, chercheur au MIT, lança le projet GNU (GNU’s Not Unix) avec l’ambition de créer un système d’exploitation entièrement libre — c’est-à-dire dont le code source serait librement accessible, modifiable et redistribuable. Sa motivation était philosophique autant que technique : Stallman estimait que le logiciel propriétaire brisait la solidarité entre programmeurs et entravait la liberté des utilisateurs. Il formula ces idées dans le Manifeste GNU (1985) et fonda la Free Software Foundation (FSF) la même année.

Le projet GNU produisit une quantité impressionnante d’outils : le compilateur GCC (GNU Compiler Collection), l’éditeur de texte Emacs, le débogueur GDB, le shell Bash (Bourne Again Shell, 1989), les utilitaires coreutils (ls, cp, mv, rm, cat, grep, awk, sed…). En 1991, le projet GNU disposait de presque tout ce qu’il fallait pour un système d’exploitation complet — sauf un élément crucial : le noyau. Le noyau GNU, appelé Hurd, souffrait de retards importants dans son développement. C’est là que Linus Torvalds allait jouer un rôle décisif.

Le noyau Linux (Torvalds, 1991)#

Le 25 août 1991, un étudiant finlandais de vingt et un ans, Linus Torvalds, posta le message suivant sur le groupe de discussion Usenet comp.os.minix :

Hello everybody out there using minix — I’m doing a (free) operating system (just a hobby, won’t be big and professional like gnu) for 386(486) AT clones.

Ce message annonçait la naissance du noyau Linux. Torvalds s’était inspiré de Minix, un système Unix pédagogique écrit par Andrew Tanenbaum, mais avait voulu créer quelque chose de plus fonctionnel et ouvert. La première version publique, Linux 0.01, parut en septembre 1991. Elle ne contenait que quelques milliers de lignes de code et tournait uniquement sur les processeurs Intel 386.

La décision déterminante fut de publier Linux sous la licence GPL (General Public License) de la FSF, ce qui signifiait que toute personne pouvait l’étudier, le modifier et le redistribuer, à condition de conserver la même licence. Cette décision transforma un projet personnel en un effort collectif mondial. Des dizaines, puis des centaines, puis des milliers de développeurs du monde entier contribuèrent des correctifs et des améliorations. La combinaison des outils GNU et du noyau Linux donna naissance à ce que l’on appelle aujourd’hui GNU/Linux — un système d’exploitation complet et entièrement libre.

Définition 1 (Le noyau Linux)

Le noyau Linux (Linux kernel) est le composant central du système d’exploitation. C’est un logiciel qui s’exécute en mode privilégié et qui fait le pont entre les programmes des utilisateurs et le matériel physique (processeur, mémoire, disques, réseau, périphériques). Il gère la mémoire, l’ordonnancement des processus, les systèmes de fichiers et les pilotes de périphériques. Le noyau Linux est développé sous la licence GPLv2 et son code source est consultable sur kernel.org.

Les distributions Linux#

Le noyau seul ne constitue pas un système utilisable. Une distribution Linux (distro) est un assemblage cohérent qui comprend le noyau Linux, les outils GNU, un gestionnaire de paquets, un environnement de bureau (facultatif), et une panoplie de logiciels préconfigurés. Chaque distribution fait ses propres choix en matière de philosophie, de cible d’utilisateurs et de compromis entre stabilité et nouveauté.

Définition 2 (Distribution Linux)

Une distribution Linux est un système d’exploitation complet bâti autour du noyau Linux. Elle regroupe le noyau, les bibliothèques système (notamment la glibc, bibliothèque C standard), les utilitaires GNU, un gestionnaire de paquets, des outils de configuration et généralement un environnement graphique. Les distributions diffèrent par leur gestionnaire de paquets, leur cycle de mise à jour, leur philosophie (stabilité vs. fraîcheur) et leur public cible.

Architecture du système#

Comprendre l’architecture d’un système Linux permet d’appréhender pourquoi les commandes que nous étudierons se comportent comme elles le font, et pourquoi certaines requièrent des privilèges particuliers.

Le noyau et ses responsabilités#

Le noyau Linux est un noyau monolithique modulaire : son code central s’exécute dans un seul espace d’adressage privilégié (l”espace noyau), mais des modules noyau peuvent être chargés et déchargés dynamiquement. Ses responsabilités sont les suivantes.

Gestion des processus. Le noyau crée, ordonnance et détruit les processus. Il décide quel processus s’exécute sur quel cœur de processeur et pendant combien de temps, selon un algorithme d’ordonnancement (scheduler). Sous Linux, l’ordonnanceur par défaut depuis la version 2.6.23 est le CFS (Completely Fair Scheduler), qui vise à distribuer équitablement le temps processeur entre tous les processus actifs.

Gestion de la mémoire. Le noyau maintient l’illusion pour chaque processus d’un espace d’adressage virtuel continu, même si la mémoire physique est fragmentée. La mémoire virtuelle permet à chaque processus de croire qu’il dispose de toute la RAM pour lui seul. Le noyau gère la pagination (paging) — l’échange de pages entre la RAM et le disque (partition swap) quand la mémoire physique est insuffisante.

Gestion des systèmes de fichiers. Le noyau implémente une couche d’abstraction appelée VFS (Virtual File System) qui permet aux programmes d’accéder à tout type de système de fichiers (ext4, btrfs, xfs, FAT32, NFS…) via une interface unique. C’est ce qui permet la philosophie « tout est fichier » : les périphériques, les sockets réseau, les processus eux-mêmes sont accessibles comme des fichiers sous /dev, /proc et /sys.

Gestion des périphériques. Les pilotes (drivers) sont des modules noyau qui traduisent les appels génériques (lire, écrire, configurer) en instructions spécifiques au matériel. Sous Linux, la plupart des pilotes sont inclus dans le code source du noyau ou disponibles comme modules chargeables.

Gestion du réseau. Le noyau implémente les protocoles réseau (TCP/IP, UDP, ICMP…) et gère les interfaces réseau physiques et virtuelles.

Remarque 1

L”espace noyau (kernel space) et l”espace utilisateur (user space) sont deux modes d’exécution du processeur. Le code s’exécutant en espace noyau a accès direct au matériel et peut exécuter n’importe quelle instruction. Le code en espace utilisateur est contraint : il ne peut accéder au matériel qu’en passant par le noyau via des appels système (system calls ou syscalls). Un programme comme ls s’exécute en espace utilisateur et, pour lire un répertoire, émet un appel système getdents64() que le noyau traite. Cette séparation est fondamentale pour la stabilité et la sécurité : un programme défaillant en espace utilisateur ne peut pas corrompre le noyau.

Les bibliothèques système#

Entre le noyau et les programmes s’intercale une couche de bibliothèques système. La plus importante est la glibc (GNU C Library), qui implémente la bibliothèque standard C et fournit des fonctions de haut niveau (printf, malloc, fopen…) par-dessus les appels système bruts du noyau. Presque tous les programmes compilés sous Linux s’appuient sur la glibc.

D’autres bibliothèques importantes sont libpthread (threads POSIX), libm (mathématiques), et les bibliothèques graphiques comme GTK ou Qt.

Le shell et les utilitaires#

Au sommet de la pile se trouvent les shells et les utilitaires. Le shell est le programme qui lit les commandes de l’utilisateur (depuis le terminal ou un fichier de script) et les traduit en appels au noyau et aux programmes. Les utilitaires GNU (ls, cp, grep, awk, sed…) sont de petits programmes qui font une chose précise et peuvent être chaînés via le shell. C’est cet écosystème que nous explorerons dans ce livre.

Principales familles de distributions#

Le paysage des distributions Linux est vaste, mais quelques grandes familles se dégagent, chacune avec son gestionnaire de paquets, sa philosophie et ses cas d’usage privilégiés.

Debian et Ubuntu#

Debian GNU/Linux (1993, Ian Murdock) est l’une des plus anciennes distributions indépendantes encore maintenues. Elle est réputée pour sa rigueur dans la sélection des paquets, sa stabilité et son attachement aux logiciels libres. Son gestionnaire de paquets, dpkg / apt (Advanced Package Tool), est l’un des plus matures de l’écosystème. Debian propose trois branches : stable (très fiable, paquets conservateurs), testing (paquets plus récents, quelques instabilités possibles) et unstable (sid, paquets de développement).

Ubuntu (2004, Mark Shuttleworth / Canonical) est dérivé de Debian et est aujourd’hui la distribution Linux grand public la plus répandue. Elle publie des versions tous les six mois (avril et octobre) avec des versions LTS (Long-Term Support) tous les deux ans, maintenues pendant cinq ans. Ubuntu et ses nombreuses variantes (Kubuntu, Xubuntu, Ubuntu Server…) ont considérablement simplifié l’installation et l’utilisation de Linux.

Exemple 1 (Gestion des paquets sous Debian/Ubuntu)

# Mettre à jour la liste des paquets disponibles
sudo apt update

# Mettre à jour tous les paquets installés
sudo apt upgrade

# Installer un paquet
sudo apt install vim

# Rechercher un paquet par nom
apt search tree

# Supprimer un paquet (en conservant ses fichiers de configuration)
sudo apt remove vim

# Supprimer un paquet et ses fichiers de configuration
sudo apt purge vim

# Afficher les informations d'un paquet
apt show vim

### Red Hat, Fedora et CentOS

**Red Hat Enterprise Linux** (RHEL) est la distribution phare de Red Hat (rachetée par IBM en 2019). Conçue pour les entreprises, elle met l'accent sur la stabilité à long terme, le support professionnel et les certifications. Son gestionnaire de paquets est **RPM** (*Red Hat Package Manager*) / **dnf** (*Dandified YUM*).

**Fedora** est la distribution communautaire sponsorisée par Red Hat, qui sert de terrain d'expérimentation pour les technologies qui seront intégrées dans RHEL. Elle est plus fraîche et plus innovante que RHEL mais moins stable sur le long terme.

**CentOS** était historiquement un clone gratuit de RHEL, très populaire sur les serveurs. Après l'annonce de Red Hat en 2020, CentOS Linux a été remplacé par **CentOS Stream**, qui précède désormais RHEL dans le cycle de développement. **AlmaLinux** et **Rocky Linux** ont émergé comme alternatives à CentOS Linux.

### Arch Linux

**Arch Linux** (2002, Judd Vinet) est une distribution minimaliste et *rolling release* : il n'y a pas de versions figées, le système est mis à jour en continu. L'installation est entièrement manuelle, ce qui la rend intimidante pour les débutants mais très populaire parmi les utilisateurs avancés qui veulent un système sur mesure. Son gestionnaire de paquets, **pacman**, est réputé pour sa simplicité et sa rapidité. L'**AUR** (*Arch User Repository*) offre un accès à des milliers de paquets communautaires.

### Alpine Linux

**Alpine Linux** est une distribution ultra-légère, basée sur **musl libc** (une alternative légère à la glibc) et **BusyBox** (qui regroupe des dizaines d'utilitaires Unix dans un seul binaire). Une image de base Alpine fait moins de 10 Mo, ce qui en fait le choix de prédilection pour les **conteneurs Docker**. Son gestionnaire de paquets s'appelle **apk**.

```{prf:remark}
:label: remark-01-02
Le choix d'une distribution dépend du contexte d'utilisation :

- **Serveurs en production** : Debian stable, Ubuntu LTS, RHEL/AlmaLinux pour le support commercial.
- **Poste de travail développeur** : Ubuntu, Fedora, Arch (pour les utilisateurs avancés).
- **Conteneurs** : Alpine Linux pour sa légèreté.
- **Systèmes embarqués** : Buildroot, Yocto (distributions spécialisées non mentionnées ci-dessus).
- **Apprentissage et expérimentation** : Ubuntu, Debian, Fedora offrent d'excellentes documentations communautaires.

Dans ce livre, tous les exemples sont écrits pour un environnement **Debian/Ubuntu**, mais les concepts et la grande majorité des commandes sont identiques sur toutes les distributions.

Frise chronologique : de Unix à Linux#

Hide code cell source

fig, ax = plt.subplots(figsize=(16, 9))
ax.set_xlim(1965, 2030)
ax.set_ylim(-5.5, 5.5)
ax.axis('off')
ax.set_title('Frise chronologique : de Unix à GNU/Linux et aux distributions',
             fontsize=15, fontweight='bold', pad=20)

palette = sns.color_palette("muted", 10)

# Ligne de temps principale
ax.axhline(0, color='#cccccc', lw=2.5, zorder=1)

# --- Événements majeurs ---
events = [
    # (année, y_offset, label, couleur)
    (1969, 2.5,  "Unix\n(Bell Labs\nThompson, Ritchie)", palette[0]),
    (1973, 1.2,  "Unix réécrit\nen C\n(Ritchie)", palette[0]),
    (1977, 2.5,  "BSD\n(Berkeley)", palette[1]),
    (1983, -2.5, "Projet GNU\n(Stallman)", palette[2]),
    (1985, -1.2, "FSF\nManifeste GNU", palette[2]),
    (1989, 2.5,  "Bash 1.0\n(Shell GNU)", palette[3]),
    (1991, -2.5, "Noyau Linux 0.01\n(Torvalds)", palette[4]),
    (1992, -1.2, "Linux 0.12\nLicence GPL", palette[4]),
    (1993, 1.2,  "Debian\n(Murdock)", palette[5]),
    (1994, 2.5,  "Red Hat\nLinux 1.0", palette[6]),
    (1999, -2.5, "Linux 2.2\n(SMP, IPv6)", palette[4]),
    (2003, 1.2,  "Fedora 1\n(dérivé Red Hat)", palette[6]),
    (2004, -1.2, "Ubuntu 4.10\n(Canonical)", palette[7]),
    (2006, 2.5,  "Linux 2.6.17\nCFS Scheduler", palette[4]),
    (2013, -2.5, "Conteneurs Docker\n(Alpine Linux)", palette[8]),
    (2022, 1.2,  "Linux 5.x/6.x\n280 000 commits", palette[4]),
]

for year, y, label, color in events:
    # Ligne verticale vers le point
    ax.plot([year, year], [0, y * 0.75], color=color, lw=1.5,
            linestyle='--', alpha=0.7, zorder=2)
    # Point sur la ligne de temps
    ax.scatter([year], [0], color=color, s=60, zorder=5)
    # Texte de l'événement
    va = 'bottom' if y > 0 else 'top'
    offset = 0.1 if y > 0 else -0.1
    ax.text(year, y * 0.75 + offset, label,
            ha='center', va=va, fontsize=7.2,
            color=color,
            bbox=dict(boxstyle='round,pad=0.25', facecolor='white',
                      edgecolor=color, alpha=0.9, linewidth=1.2))

# Marqueurs d'années sur la ligne de temps
for yr in range(1970, 2026, 5):
    ax.text(yr, -0.35, str(yr), ha='center', va='top',
            fontsize=8, color='#555555')
    ax.plot([yr, yr], [-0.1, 0.1], color='#aaaaaa', lw=1, zorder=3)

# Légende des grandes familles
legend_items = [
    (palette[0], "Unix / BSD"),
    (palette[2], "Projet GNU"),
    (palette[4], "Noyau Linux"),
    (palette[3], "Outils GNU (Bash)"),
    (palette[5], "Debian"),
    (palette[7], "Ubuntu"),
    (palette[6], "Red Hat / Fedora"),
    (palette[8], "Conteneurs"),
]
for i, (color, label) in enumerate(legend_items):
    ax.scatter([], [], color=color, s=60, label=label)
ax.legend(loc='lower right', fontsize=8, framealpha=0.9,
          title="Familles", title_fontsize=9)

plt.tight_layout()
plt.show()
_images/aa99f8e91f47fdb495724c844201b77b31c94f3441a470d8f4bc439300439b0d.png

La philosophie Unix et son héritage#

La philosophie Unix mérite que l’on s’y attarde, car elle explique la cohérence des outils que l’on étudiera tout au long de ce livre. Cette philosophie, formulée par Doug McIlroy, Mike Lesk et Joe Ossanna, peut se résumer en trois règles :

  1. Chaque programme ne fait qu’une seule chose, mais il la fait bien. grep cherche des motifs dans du texte. sort trie des lignes. wc compte des mots, des lignes et des caractères. Aucun de ces programmes ne prétend tout faire.

  2. Les programmes communiquent via des flux de texte standard. Chaque programme lit depuis l’entrée standard (stdin) et écrit sur la sortie standard (stdout). Cette uniformité permet de les enchaîner avec le symbole | (pipe) pour construire des traitements complexes à partir de briques simples.

  3. Préférez les logiciels portables et interopérables. Le texte brut est universel. Un fichier de configuration en texte clair est lisible par n’importe quel éditeur, transformable par n’importe quel outil de traitement de texte, et versionnable avec Git.

Exemple 2 (La philosophie Unix en action)

L’exemple suivant illustre comment plusieurs programmes simples peuvent être chaînés pour accomplir une tâche complexe — ici, trouver les dix adresses IP qui apparaissent le plus souvent dans un journal d’accès web :

# Extraire la première colonne (adresse IP) du fichier de log,
# trier, dédoublonner avec comptage, re-trier par fréquence
# et afficher les dix premières
cat /var/log/nginx/access.log \
  | awk '{print $1}' \
  | sort \
  | uniq -c \
  | sort -rn \
  | head -10

Chaque programme (awk, sort, uniq, head) est minuscule et fait une seule chose. Leur combinaison via des pipes est puissante et lisible.


## La standardisation POSIX

Un aspect crucial de l'écosystème Unix/Linux est la **standardisation POSIX** (*Portable Operating System Interface*). Défini par l'IEEE, POSIX est une famille de normes qui spécifie l'interface des systèmes d'exploitation compatibles Unix : les appels système, les utilitaires de la ligne de commande, les expressions régulières, les threads, et bien plus.

```{prf:definition} POSIX
:label: definition-01-03
**POSIX** (*Portable Operating System Interface*) est une famille de normes IEEE (IEEE 1003) qui définit l'interface d'un système d'exploitation compatible Unix. Elle spécifie notamment : les appels système C (`open`, `read`, `write`, `fork`, `exec`…), le comportement des utilitaires de la ligne de commande (`ls`, `grep`, `awk`, `sed`…), le comportement du shell (Bourne shell), et les expressions régulières de base (BRE) et étendues (ERE). La conformité POSIX garantit qu'un script ou un programme fonctionnera sur tout système certifié — Linux, macOS, Solaris, BSD.

La conformité POSIX est l’une des raisons pour lesquelles Bash est si omniprésent : il est compatible POSIX (en mode --posix ou avec le shebang #!/bin/sh) et garantit ainsi la portabilité des scripts entre systèmes Linux, macOS, BSD et même Windows (via WSL ou Cygwin).

Le modèle « tout est fichier »#

L’une des abstractions les plus puissantes héritées d’Unix est le principe selon lequel tout est fichier. Sous Linux, non seulement les fichiers ordinaires et les répertoires sont des fichiers, mais aussi :

  • Les périphériques : /dev/sda (premier disque dur), /dev/tty1 (premier terminal virtuel), /dev/null (poubelle de données), /dev/random (générateur de nombres aléatoires).

  • Les processus : le répertoire /proc/[pid]/ contient des informations sur chaque processus en cours d’exécution. Par exemple, /proc/1234/cmdline contient la ligne de commande du processus 1234.

  • Les paramètres noyau : /sys/ expose les paramètres du noyau et des périphériques sous forme de fichiers.

  • Les sockets réseau : sous certaines conditions, les connexions réseau peuvent être manipulées comme des fichiers.

Remarque 2

Le modèle « tout est fichier » a une conséquence pratique immédiate : les mêmes outils (cat, echo, read, write, redirections) peuvent manipuler des fichiers ordinaires, des périphériques et des processus. Par exemple :

# Lire la température du processeur (exposée comme un fichier)
cat /sys/class/thermal/thermal_zone0/temp

# Envoyer des données vers le périphérique null (les oublier)
commande_bruyante > /dev/null 2>&1

# Lire la ligne de commande du processus 1 (systemd ou init)
cat /proc/1/cmdline

## Résumé

Dans ce premier chapitre, nous avons posé les fondations historiques et conceptuelles du système Linux :

- **Unix** (1969, Bell Labs) a introduit les concepts fondateurs : la philosophie « faire une chose et la faire bien », les pipes, la hiérarchie de répertoires, les permissions. La réécriture en C (1973) a rendu Unix portable.
- **Le projet GNU** (Stallman, 1983) a produit les outils essentiels (GCC, Bash, coreutils) et la licence GPL, mais manquait d'un noyau opérationnel.
- **Le noyau Linux** (Torvalds, 1991), publié sous GPL et développé collaborativement, a comblé ce manque. La combinaison GNU/Linux forme un système complet et libre.
- **L'architecture** du système s'organise en couches : matériel → noyau (gestion des processus, de la mémoire, des fichiers, des périphériques) → bibliothèques système (glibc) → shell et utilitaires.
- **Les distributions** (Debian/Ubuntu, Red Hat/Fedora, Arch, Alpine) sont des assemblages cohérents autour du noyau Linux, différenciés par leur gestionnaire de paquets, leur cycle de mise à jour et leur philosophie.
- La **philosophie Unix** — programmes minimalistes communiquant via des flux de texte — et le principe **POSIX** garantissent la portabilité et la composabilité des outils.

Dans le prochain chapitre, nous découvrirons le **terminal** et le **shell** — l'interface entre l'utilisateur et ce système — et nous commencerons à prendre en main Bash, l'interpréteur de commandes qui sera notre outil principal tout au long de ce livre.