Retour à la constellationPROARKHEAtlas personnel

Systèmes UNIX

42sh

Reconstruire un shell POSIX pour comprendre ce qui se passe entre une commande et son exécution.

2025Terminé
PROARKHEL'origine

Un shell donne l’impression d’être un programme assez direct : il reçoit une ligne de texte et lance une commande. 42sh montre rapidement tout ce qui se cache entre ces deux étapes. Avant d’exécuter quoi que ce soit, il faut reconnaître la structure de la commande, comprendre les opérateurs utilisés et représenter correctement leurs relations.

Réalisé pendant quatre semaines en équipe de quatre, le projet constituait une synthèse de notre période C et UNIX. Il fallait construire plusieurs sous-systèmes distincts tout en respectant les contraintes du C99, le fonctionnement de POSIX et le comportement d’un shell de référence.

COMMANDEPARSERASTCONTEXTEEXÉCUTION

Le traitement d’une commande suivait plusieurs étapes. Le texte saisi devait être découpé, analysé par le parser puis transformé en arbre syntaxique abstrait. Cet AST permettait de conserver la hiérarchie réelle de la commande au lieu de manipuler une simple succession de mots.

Je me suis occupé d’une partie du parser ainsi que de la gestion de l’AST. J’ai également travaillé sur l’exécution générale : parcourir l’arbre, reconnaître le type de chaque nœud et déclencher le comportement correspondant en tenant compte du contexte courant.

Cette partie se trouvait au croisement de nombreux composants. Une différence dans la construction de l’arbre pouvait modifier l’ordre d’exécution ou provoquer un comportement incorrect bien plus tard. Il fallait donc définir des interfaces claires avec le reste de l’équipe et tester les commandes autant individuellement qu’en combinaison.

Architecture complète du projet 42sh
Architecture complète du projet 42sh

Développement d’une partie du parser, prise en charge de l’AST et mise en place de la logique générale d’exécution selon le type de commande et son contexte.

42sh

03

Analyse

Transformer une commande en structure

Le parser ne devait pas simplement reconnaître des mots. Il devait comprendre les relations entre les commandes, les opérateurs et les structures de contrôle, puis construire un arbre qui conservait leur ordre et leur priorité.

Cette représentation était essentielle : l’exécuteur pouvait ensuite travailler sur des nœuds clairement identifiés plutôt que réinterpréter directement la chaîne saisie par l’utilisateur.

Transformation d’une ligne de commande en arbre syntaxique abstrait
Le parser transforme une commande linéaire en une structure exploitable

Exécution

Donner un comportement à chaque nœud

Une fois l’AST construit, chaque nœud devait être exécuté selon sa nature et le contexte dans lequel il apparaissait. Une commande simple, une condition ou une composition de commandes ne suivent pas exactement les mêmes règles.

La difficulté ne venait donc pas seulement de chaque fonctionnalité prise séparément, mais de leurs interactions et de la propagation correcte des résultats, des erreurs et des statuts de sortie.

Organisation

Faire évoluer plusieurs sous-systèmes ensemble

Le projet avançait par rendus hebdomadaires. Cette progression imposait de conserver une base fonctionnelle tout en ajoutant progressivement de nouveaux comportements.

Dans une équipe de quatre, les choix de structures et d’interfaces avaient un impact immédiat sur le travail des autres. Le projet demandait donc autant de rigueur dans l’organisation du code que dans son implémentation.

Ce projet a rendu beaucoup plus concret le fonctionnement des outils que j’utilisais quotidiennement dans un terminal. Une redirection, un pipeline ou une structure conditionnelle n’était plus seulement une syntaxe connue : je pouvais suivre sa transformation depuis les caractères saisis jusqu’aux appels système nécessaires à son exécution.

42sh m’a également appris à raisonner sur un programme dont les composants sont fortement liés. Le parser, l’AST et l’exécution doivent avancer ensemble : une représentation bien pensée simplifie la suite, tandis qu’une approximation au début du traitement finit presque toujours par réapparaître ailleurs.

CC99PXPOSIXUXUNIXATAutotoolsGGit
Projet suivantUpside Down