Pourquoi UNIX ?
En 1982 le service des relations publiques de Bell Labs commande une vidéo à la société de production EWB Productions. Cette vidéo présente l’une des productions phare du laboratoire, le système d’exploitation Unix. Le système a alors déjà 13 ans et est utilisé quotidiennement dans le laboratoire. La vidéo présente l’adaptation du logiciel aux nouveaux besoins de ces utilisateurices comme l’enjeu majeur du développement logiciel, contrairement à la conception de biens matériels :
When you build hardware and send it out, you may have to fix because it breaks but you don’t demand for example that your radio suddenly turns into a television.
Il est donc nécessaire de pouvoir modifier facilement et fréquemment le logiciel pour l’adapter aux besoins. Deux solutions sont proposées : 1. écrire du code d’une manière qui soit très claire, structurée et facile à modifier. 2. écrire de nombreux petits modules de code de façon à n’avoir à jeter ou modifier que quelques modules à la fois plutôt que de jeter “des milliers et milliers de lignes de code à la fois”1.
Si vous vous êtes déjà retrouvé·es bloqué·es par un·e fan d’Unix dans une longue conversation au sujet de son élégance vous reconnaitrez que la solution retenue par Bell Labs est plutôt la seconde. La stratégie est alors de rédiger ces petits modules et de faire manipuler ces primitives aux développeureuses de façon à ce qu’iels évoluent dans un niveau d’abstraction plus élevé, plus expressif, qui mènera à moins de code écrit et donc potentiellement moins de code à modifier/jeter.
Les primitives, blocs d’assemblage
Brian W. Kernighan, l’un des chercheurs les plus impliqué dans la création d’Unix et co-auteur avec Denis Ritchie du premier bouquin sur le langage C, embraye sur un ressenti toujours d’actualité : le logiciel semble passer le plus clair de son temps à nous compliquer la tâche plutôt qu’à la faciliter. Selon lui pour remédier à ce problème il faut des logiciels de “haut-niveau” faciles à manipuler et à combiner ensemble2. Dans le visuel suivant ce sont les utilitaires :

Ces logiciels, qu’il décrit comme des blocs à assembler, sont les modules auxquels la vidéo faisait référence au début. Pris isolément ils ne font pas grand chose d’intéressant mais Unix propose une abstraction permettant de les combiner entre eux pour faire émerger de nouvelles fonctionnalités. Et c’est là que notre démo entre en jeu.
La démo

Cette image montre à gauche le début de l’enchainement des utilitaires et à
droite les fonctions qu’elles remplissent. On prend le contenu dans le fichier
texte sentence, on le déplie pour avoir une ligne par mot, on met tout en
minuscule, on trie par ordre alphabétique, on supprime les doublons et on
compare le résultat avec un dictionnaire anglais. Dans la vidéo Kernighan
utilise cette commande :
makewords sentence | lowercase | sort | unique | mismatch
Le caractère | étant la manière de combiner les commandes. Elle lie les
primitives les unes avec les autres sur le modèle “le résultat de la commande à
gauche devient l’entrée sur laquelle celle de droite opère”. Si l’on
visualisait le résultat à chaque étape cela donnerait :
Le contenu d'origine :
At Bell Laborotories
UNIX systems privide
more timesharing ports
than all other systems
combined
makewords sentence | lowercase | sort | unique | mismatch
| | | | |
v v v v v
At at all all laborotories
Bell bell at at privide
Laborotories laborotories bell bell timesharing
UNIX unix combined combined unix
systems systems laborotories laborotories
privide privide more more
more more other other
timesharing timesharing ports ports
ports ports privide privide
than than systems systems
all all systems than
other other than timesharing
systems systems timesharing unix
combined combined unix
Il se trouve que l’on peut très facilement, en 2026, 43 ans plus tard, reproduire la démo à l’identique (je viens d’exécuter ça sur mon PC, svp croyez moi, les personnes ayant assisté à cette présentation sont témoins) :
makewords sentence | lowercase | sort | uniq | mismatch
laborotories
privide
timesharing
unix
J’ai contacté Kernighan par mail pour lui demander ce qui se cachait derrière
les commandes makewords, lowercase et mismatch. Voici sa réponse :
Some (most?) of the commands in that pipeline were existing commands, just renamed to be more intuitive to someone who hadn’t seen it before. So “mismatch” is comm with the right arguments, “makewords” was probably tr with arguments, and so was lowercase.
Kernighan décrit ici le concept expliqué par Lorinda
Cherry3 à partir de 15m37s
dans la vidéo. En résumé il est possible de créer une nouvelle commande toto
en écrivant des commandes dans un fichier nommé toto. Si l’on tente
d’exécuter le fichier le système va le lire et exécuter les commandes à
l’intérieur. On encapsule ainsi une ou plusieurs commandes dans une autre, pour
des raisons sémantiques par exemple.
Puisque le texte source est en ascii4 je parierai sur le fait que makewords
est en réalité une encapsulation de tr ' ' '\012'56, lowercase
serait tr A-Z a-z et mismatch serait comm -23 - dict, dict étant le
fichier contenant le dictionnaire7. La commande exécute donc en “réalité” ce
qui suit, mais à la limite peu importe :
< sentence tr ' ' \012 | tr A-Z a-z | sort | uniq | comm -23 - dict
Cette facilité à reproduire un programme d’un langage haut niveau, 43 ans plus tard, à l’identique et sans avoir rien eu à installer ou bidouiller est à mon sens assez remarquable et l’une des raisons fondamentales pour lesquelles, malgré toutes ses limites, contraintes et étrangetés, je mise sur le shell Unix et ses primitives traditionnelles pour créer du logiciel durable. Le fait que ce système d’exploitation et ses primitives aient eu autant de succès est à la fois une malédiction, puisqu’elle force quiconque cherche à devenir familier ou familière avec la ligne de commande Unix à se farcir tout un tas d’incohérences et un modèle d’interaction figé dans le temps8, et une bénédiction puisqu’il rend cet environnement d’assez haut niveau très stable et pérenne, une immense partie de l’informatique en dépendant.
Stable, vraiment ?
Si le fait que l’écriture et le comportement de ces commandes n’aient pas changé
est un constat intéressant en soit, s’arrêter là serait dommage. Les versions
des commandes utilisées en 1982 et celles que j’utilise aujourd’hui ne sont pas
les mêmes. D’un oeil extérieur sort et sort sont identiques mais le code
a changé.
Je ne veux pas rentrer dans les détails pour cet article mais je jette en vrac des questions à creuser pour plus tard :
En 1982
sort
faisait 900 lignes et la plus répandue
aujourd’hui,
celle des GNU coreutils, fait 4989 lignes. Plusieurs hypothèses pourraient
l’expliquer. Du code doit être ajouté pour implémenter des algorithmes plus
sophistiqués pour trier plus vite. Du code doit être ajouté pour faire usage de
l’architecture plus complexe des processeurs modernes9. Des fonctionnalités
ont été ajoutées (voir quelques paragraphes plus bas). Les primitives sont
aujourd’hui distribuées toutes ensemble avec un certain niveau de factorisation
de code entre elles permettant certainement d’économiser des lignes mais créant
aussi du boilerplate. Les GNU
coreutils ciblent une diversité bien plus grande d’architecture qu’Unix V7 etc.
La version de 1982 importe 5 .h de base, celle de GNU importe 34 .h.
Le sort de 1982 compile10 sur mon ordinateur faisant tourner debian 13 en
2026 avec la commande gcc --ansi sort.c mais termine directement avec un
segmentation fault. Peut-être que le problème n’est pas complexe à résoudre,
reste que la stabilité du C derrière notre pipe n’est pas garantie. Certainement
parce que les librairies appelées par sort.c ont trop changé depuis.
L’ordinateur sur lequel Kernighan fait sa démo est incommensurablement plus lent
que celui que j’utilise aujourd’hui. Le kernel Linux ne pourrait pas tourner
dessus et donc certainement pas le sort d’aujourd’hui. A moins de précher pour
une stabilisation complète des ressources en calcul dès 1982 ce n’est pas très
raisonnable de reprocher au sort moderne de consommer plus de ressources.
Une mesure plus intéressante serait de comparer, pour une métrique donnée, à
quel point il est coûteux de faire tourner le sort du moment. Par exemple
dans un article de blog Dan Luu remarque
que le prix par unité de mémoire a baissé beaucoup plus vite que la taille des
binaires et leur consommation en RAM11 et qu’il est donc un peu futile de se
plaindre de cette croissance. sort a “grossi” mais il n’a jamais été aussi
peu cher en mémoire de le faire fonctionner. Étudier cela sur le coût financier
est une chose mais on pourrait peut-être se poser la même question pour un coût
environnemental.
Toujours dans l’article de Dan Luu, il est montré que les commandes couvrent
aujourd’hui beaucoup plus de fonctionnalités qu’auparavant, la quantité
d’option servant de proxy pour la quantité de fonctionnalités. Le monde du
terminal n’est donc pas entièrement immunisé contre ce phénomène. sort n’est
pas renseigné dans l’article mais un exemple typique serait ls, commande
listant des fichiers, étant passée de 11 options en 1979 à 58 en 2017, toujours
pour lister des fichiers. Cette augmentation fait l’objet de débats enflammés
dans la communauté Unix jusqu’à la création de sites dont
le nom de domaine est une référence directe à l’une de ces
controverses. Cela dit on constate que
l’augmentation semble ralentir mais puisque les deux dernières dates auxquelles
il a fait le calcul sont beaucoup plus rapprochées que les autres il est
impossible de conclure. Refaire l’exercice pour 2026 pourrait permettre de
confirmer ou infirmer l’hypothèse selon laquelle l’ajout d’option a atteint un
plateau.
Annexes
Une seconde vidéo très similaire mais présentant des démos un peu différentes :
-
ce qui n’est pas grand chose aujourd’hui mais représente beaucoup à l’époque. ↩
-
je pense que les concepteurs d’Unix cherchaient fondamentalement à répondre aux mêmes problèmes que les chercheur·euses en IHM d’aujourd’hui. A ceci près que les interfaces répandues et les compétences d’une personne typique utilisatrice d’ordinateur de l’époque les ont pousser à concevoir une solution impliquant d’écrire du code haut-niveau dans un terminal là où aujourd’hui elle serait de concevoir une interface graphique intuitive. Pour reprendre un stéréotype éculé et problématique : “madame michu” existait déjà conceptuellement à l’époque mais on lui faisait invoquer une commande toute faite dans un terminal voir elle écrivait elle même sa commande avec quelques pipes. Les professionnels de l’informatique écrivaient du C pour construire les primitives de ces commandes. ↩
-
co-autrice du Writer’s Workbench, un logiciel aidant à l’écriture de l’anglais incluant un mode de détection de mots jugés sexistes. Une démo datant de 1981 est consultable ici. ↩
-
à l’époque sur de l’Unix c’était très très probablement le cas, je n’ai pas vérifié pour savoir si le système supportait d’autres encodages en 1982 mais il est possible que non ↩
-
Et pas
tr ' ' '\n'puisqu’étant donné la date l’Unix utilisé dans la vidéo est probablement Unix V7 et sa version detrsemble ne pas supporter l’écriture du caractère nouvelle ligne comme ‘\n’ mais supporte l’écriture en octal\012. ↩ -
ou
tr -cs A-Za-z'ICI-LITTERALEMENT-LE-CARACTERE-NOUVELLE-LIGNE-MAIS-JE-PEUX-PAS-LINSERER-PARCE-QUIL-EST-INVISIBLE'comme dans cet article comparant les solutions de McIlroy et Knuth a un problème de programmation. Ce duel est ensutie devenu légendaire depuis et souvent utilisé un peu à tort et à travers pour “prouver” la supériorité des pipes sur d’autres styles de programmation. La pipline de McIlroy commence d’ailleurs exactement comme celle de Kernighan dans la démo, seule la dernière commande est différente. ↩ -
sur ma machine un dictionnaire anglais se trouve à
/usr/share/dict/words↩ -
alors que tout un tas de bonnes idées et critiques ont émergé depuis. Voir par exemple ce blog qui en regorge. ↩
-
un phénomène que Dijkstra expliquait déjà dans son discours The Humble Programmer en 1972. Il rendait compte de la manière dont cette complexité et puissance supplémentaire, allait faire du développement une pratique très complexe, capable de beaucoup, valant le coup d’être étudiée scientifiquement et donc associée à un certain prestige. Cela résonne particulièrement bien avec les travaux d’Isabelle Collet ou Felienne Hermans. La disparition des femmes de cette industrie qu’elles racontent coïncide chronologiquement avec la période évoquée par Dijkstra. D’ailleurs on notera qu’il désigne toujours le “programmer” au masculin, même pour parler de l’époque durant laquelle ce n’était pas un métier particulièrement genré. ↩
-
avec des warnings que je n’ai pas pris le temps de corriger ↩
-
cela dit rien ne garanti que cette tendance perdure, cf le prix de la RAM début 2026. ↩