This is an old revision of the document!
Le but de ce thème est de créer un shell simple, compatible avec sh
;
fork
, exec
et waitpid
, …)Le devoir doit etre résolu individuellement. Toute tentative de tricher entraînera 0p pour ce devoir. Nous utiliserons également des systèmes de détection de trichage automatique. Si nous avons des doutes, nous vous poserons des questions supplémentaires concernant le devoir.
Si vous avez des questions concernant le devoir, posez-les en publiant un issue sur le github https://github.com/UPB-FILS-SdE2/questions avec le format [busybox] <le titre de votre question> . Vous aurez besoin d'un compte github pour publier des questions.
Si vous voulez recevoir un e-mail lorsque des problèmes sont signalés ou lorsqu'il y a de nouveaux messages, accédez au site github repository et cliquez sur Watch.
Implémentez un shell simple qui prend en charge l'exécution de commandes externes avec plusieurs arguments, commandes internes, redirections, canaux. Le shell doit gérer l'exécution de commandes composées avec plusieurs opérateurs.
cd
, pwd
, exit
…
Commandes externes: Les commandes qui sont en fait des exécutables séparés: ls
, vim
, arbre
, nano
, …
La règle est la suivante: vérifiez si la commande interne est, sinon, on suppose qu'elle est une commande externe.
Le shell doit prendre en charge les opérateurs d'exécution suivants:
;
expr1; expr2
commencera par exécuter les commandes expr1
et les commandes expr2
seulement après l'exécution de expr1; &
expr1 & expr2
entraînera l'exécution de expr1
et des commandes expr2
en parallèle;execv ("./rustyshell", "command");
&&
et ||
expr1 && expr2
n'exécutera les commandes expr2
que si la commande expr1
génère un code d'erreur '0' '; expr1 || expr2
n'exécutera les commandes expr2
que si les commandes expr1
génèrent un code d'erreur différent de zéro. |
est interpolé entre deux commandes. L'effet est la redirection de ce que le premier processus écrit sur l'écran vers ce que le deuxieme processus lit du clavier . Par exemple, expr1 | expr2
entraînera l'exécution des commandes expr1
avec la sortie standard redirigée vers le stdin des commandes expr2
;La priorité des opérateurs d'exécution est, de la priorité la plus grande à la plus petite:
Le shell doit également prendre en charge les redirecteurs suivants:
< nom_fichier
pour rediriger l'entrée standard à partir du fichier nom_fichier
; > nom_fichier
pour rediriger la sortie standard vers le fichier nom_fichier
; 2> nom_fichier
pour rediriger la sortie d'erreur standard vers le fichier nom_fichier
; &> nom_ficher
pour rediriger la sortie standard et la sortie d'erreur standard vers le fichier nom_fichier
; >> nom_fichier
pour rediriger la sortie standard vers le fichier nom_fichier
en mode append ; 2 >> nom_fichier
pour rediriger la sortie d'erreur standard vers le fichier nom_fichier
en mode append .Finalement, le shell doit accepter les commandes internes suivantes:
exit
et quit
pour terminet le shell cd directory
pour changer le répertoire actuel cd
sans paramètre, remplacer le répertoire en cours par le répertoire home de l'utilisateur courant (variable
* pour celles-ci, on va exécuter tout ce qu'on trouve entre les paranthese et le résultat sera remplacé dans la liste de commandes
==== Remarques générales ====
* Pour simplifier la mise en oeuvre du devoir, vous pouvez utiliser l' analyseur mis en œuvre par nous. Pour plus de détails sur l’analyseur, lisez le fichier README dans l’archive. Des exemples d'utilisation de l'analyseur peuvent être trouvés dans la source
cmd.py , qui peut etre utilisée comme un support pour le devoir.
* Le prompt affiché par le shell est requis pour faciliter les tests automatiques et est $ (c'est-à-dire qu'il affichera le caractère $ suivi d'un espace blanc).
* Le nom de l'exécutable du devoir doit être
cmd.py .
==== Suggestions ====
Le devoir est relativement complexe par rapport au précédent. Un modèle pour le commencement du devoir est disponible sur le repository dans le répertoire tema3 .
Nous vous recommandons de résoudre et de tester toujours le devoir, étape par étape:
- Lancer des commandes simples (
ls ,
ls -l )
- Exécuter des commandes internes (
cd ,
exit , 'quit' ')
- mise en place de redirections (opérateurs
< ,
> ,
2> ,
&> ,
» ,
2» )
- séquencement des commandes (opérateurs
&&,
||,
;)
- implémentation des opérateurs
& (parallèle)
-
|
* Voici quelques exemples de commandes et le résultat généré par celles-ci:
<code bash>
$ ls
Makefile README.checker mini-shell mini-shell.o parser
Makefile.checker inputs mini-shell.c outputs tags
$ cat /etc/services | grep telnet
telnet 23/tcp
rtelnet 107/tcp # Remote Telnet
rtelnet 107/udp
telnets 992/tcp # Telnet over SSL
telnets 992/udp
tfido 60177/tcp # fidonet EMSI over telnet
$ uname -a ; ps
Linux bogdan-desktop 2.6.31-19-generic #56-Ubuntu SMP Thu Jan 28 02:39:34 UTC 2010 x86_64 GNU/Linux
PID TTY TIME CMD
6078 pts/0 00:00:00 bash
6190 pts/0 00:00:00 mini-shell
6200 pts/0 00:00:00 ps
$ date && sleep 1 ; echo date
Mon Feb 8 13:40:25 EET 2010
date
$ date && sleep 1; date
Mon Feb 8 13:40:49 EET 2010
Mon Feb 8 13:40:50 EET 2010
$ true && date
Mon Feb 8 13:41:16 EET 2010
$ false && cat mini-shell.c
$ false || date
Mon Feb 8 13:42:36 EET 2010
$ cat /et/services
cat: /et/services: No such file or directory
$ gcc > tmp; echo sep; cat tmp
gcc: no input files
sep
$ strace -e trace=read ls 2> strace.out
Makefile README.checker mini-shell mini-shell.o parser tags
Makefile.checker inputs mini-shell.c outputs strace.out tmp
$ head -1 strace.out
read(3, “\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0@#\0\0\0\0\0\0@”…, 832) = 832
$ pwd; cd Teme; pwd
/home/bogdan/Documents/SO/Solutii
/home/bogdan/Documents/SO/Solutii/Teme
$ LETTER=alfa && echo $LETTER
alfa
> echo a > test ; echo b » test && cat test
a
b
> exit</code>
===== Documents d'aide =====
Cours utiles:
*Cours 1 - Introduction
*Cours 2 - Système de fichiers
*Cours 3 - Système de fichiers
*Cours 4 - Processus
*Cours 5 - Planification
Laboratoires utiles:
*TP 02 - Linux
*TP 2 - Python
*TP 3 - Fonctions d'entrée et sortie
*TP 07 - Processus 2
*TP 5 - IPC - Communication entre processus
Ressources:
* L'analyseur de commandes, le modèle de code et les tests sont disponibles dans tema3 sur le repository de Github.
===== Traitement de la ligne de commande =====
Pour traiter la ligne de commande, nous avons déjà écrit un analyseur que vous pouvez utiliser.
Lancez le devoir dans le fichier 'cmd.py' du modèle.
Pour voir à quoi ressemble la structure de données à partir de l'analyseur, exécutez le script cmd.py et apres introduisez une commande du clavier.
<note warning>
Pour pouvoir exécuter le fichier cmd.py, il faut intaller la bibliotheque bashlex (
pip3 install bashlex --target=.).
</note>
<code bash>
$ pip3 install bashlex –target=.
$ python3 cmd.py
$ ls
ls
{'op': 4, 'com1': None, 'com2': None, 'commands': [<parse.SimpleCommand object at 0x100b4bfd0>], 'input': None, 'output': None, 'err': None, 'append_err': False, 'append_out': False}
commands
ls
</code>
===== La structure retournée en cmd.py =====
En appelant parse.parse(line), on va renvoyer un objet de type Command.
==== Classe Command ====
Propriétés:
* op - le type d'opération de la commande (les types sont définis en bas)
* com1 - contient un objet de type Command, la premiere commande de la liste, si op est OP_NONE, com1 sera égal a None
* com2 - contient un objet de type Command, la deuxieme commande de la liste, si op est OP_NONE, com2 sera égal a None
* commands - contient la liste des commandes et argumens ( seulement si op est OP_NONE), si l'un des arguments est de la forme
et
$ PWD ), historique, etc. - (voir man bash pour une idée de la fonctionnalité d'un shell complet
)
* Q: Puis-je utiliser l'analyseur si je veux écrire un autre équivalent?
* A: Oui.
* Q: Nous sommes autorisés à utiliser:
<code>
args = [”/bin/bash”, ”-c”, command];
os.execv(args[0], args);
</code>
* A: Non.
* Q: Puis-je faire
os.execv '' sur mon devoir pour exécuter une partie de l'arbre indépendamment?Le devoir sera téléchargé sur vmchecker. Connectez-vous au site à l'aide de l'utilisateur moodle, sélectionnez Systemes d'Explotation (FILS) et chargez archive de devoir.
Le fichier readme a le format suivant:
Votre nom entier La groupe Description de la résolution du devoir, pourquoi vous avez choisi des solutions, etc.
Pour télécharger le devoir, suivez les étapes suivantes:
N'incluez PAS les directoires spécifiques a la bibliotheque bashlex (pycache, bashlex, bashlex-0.14.dist-info).
Après avoir chargé l'archive, vmchecker s'exécutera:
unzip archive.zip homework cd homework python3 cmd.py