Projet de Systèmes II (licence 2000-2001)

L'auteur de cette page est : Jean-Baptiste Yunes

Généralités

Il s'agit d'implémenter un mini shell avec contrôle de processus.

Ce projet devra être réalisé en langage C en utilisant les fonctions POSIX étudiées en cours. Il devra impérativement fonctionner sur les machines de l'UFR. Le travail pourra être effectué par groupe de quatre étudiants au plus. Un rapport devra être rédigé et rendu avant la soutenance. Les dates de remise des rapports et soutenances seront précisées ultérieurement.

Le shell

Comme tout shell qui se respecte celui-ci possède différentes commandes internes dont (au moins) les suivantes (commande représente n'importe quelle commande Unix avec ses arguments) :

cd [ répertoire ]
commande permettant de changer de répertoire courant
status
commande permettant d'obtenir le code de retour de la dernière commande exécutée. Celle-ci fonctionnant toujours normalement.
set variable [ valeur ]
commande permettant de créer/modifier une variable non exportée de l'environnement.
unset variable
commande permettant de supprimer une variable d'environnement.
setenv variable
commande permettant de rendre héritable une variable d'environnement.
unsetenv variable
commande permettant de supprimer l'attribut héritage d'une variable d'environnement.
show
commande permettant de lister les variables d'environnement.
run ( commande )
commande permettant de lancer une commande en mode détaché (arrière-plan).
redirect (fichier-entrée, fichier-sortie , fichier-erreur ,commande)
commande permettant de lancer une commande dont les entrées/sorties sont redirigées. Si un fichier est absent alors il n'y a pas de redirection correspondante.
pipe ( commande , commande )
commande permettant de lancer deux commandes communiquant par un tube anonyme.

Ce shell devra en outre permettre un contrôle des commandes par l'intermédiaire des commandes internes suivantes :

jobs
commande permettant de lister les commandes sous le contrôle.
killj signal numéro-de-commande
commande permettant d'envoyer un signal donné à la commande sous le contrôle.
fg numéro-de-commande
commande permettant de reprendre une commande en mode interactif.
bg numéro-de-commande
commande permettant de reprendre une commande suspendue en mode détaché.

Outre les variables standard, certaines variables de l'environnement sont prédéfinies de la façon suivante :

PROMPT
qui permet de contrôler la chaîne d'invite. On pourra y placer les caractères magiques suivants :
%H
pour représenter l'heure courante.
%M
pour représenter les minutes courantes.
%S
pour représenter les secondes courantes.
%P
pour afficher le répertoire courant.
MAXJOBS
permettant de modifier le nombre maximal de commandes sous le contrôle du shell (0 pas de limitation).
MAXTIME
permettant de contrôler la durée maximale d'exécution d'une commande (0 pas de limite). La durée est exprimée en secondes.

Un exemple de session pourrait être le suivant :

Il est 13h30. '/ens/yunes' > cd /tmp
Il est 13h30. '/tmp' > ls -ail
...(résultat de ls -ail)...
Il est 13h31. '/tmp' > status
0
Il est 13h31. '/tmp' > show
...
(exportée)PROMPT:Il est %H:%M. '%P' >
(exportée)MAXTIME:0
(exportée)MAXJOBS:0
(locale  )x:fsdjkfsdfsdmlfkd
(exportée)HOME:/ens/yunes
...
Il est 13h32. '/tmp' > vi truc
...(frappe de ^Z)
Commande 'vi truc' suspendue numéro de commande attribué : 0
Il est 13h33. '/tmp' > jobs
0: vi truc
Il est 13h33. '/tmp' > fg 0
...(reprise de vi puis sortie)
Il est 13h37. '/tmp' > pipe ( ls -ail , more )
...(résultat de ls -ail pipé dans more)
Il est 13h38. '/tmp' > pipe ( redirect ( /etc/motd , , , cat ) , more )
...(résultat de "cat </etc/motd | more")

Le travail à réaliser

Le strict minimum est d'implanter les commandes cd, status, run, jobs, killj, fg et bg. Ensuite, essayez pipe et redirect. Et finissez par la gestion des variables.

La grammaire de commande du shell n'est pas à considérer comme stricte, toutefois je vous conseille de ne pas trop vous en écarter. Ceux qui désirent écrire un parseur en utilisant lex/yacc ou flex/bison doivent savoir que c'est plutot délicat. Concentrez-vous sur l'essentiel.