Devoir 2 - Rustyshell

Le but de ce thème est de créer un shell simple, compatible avec sh ;

Informations générales

Date limite: Le 16 avril, 23h59
Note: 2 points de la note
Lien: Devoir 2
Télécharger en retard: 1 points / jour (maximum 4 jours)

Connaissances précieuses

  • Utiliser les fonctions de la biblioteques std et nix pour travailler avec des fichiers
  • Utiliser les fonctions de la biblioteques nix pour travailler avec des processus (fork, exec et waitpid , …)
  • Comprendre les principes de travail avec les fichiers et les processus

Règles

  1. Le devoir doit contenir un fichier Readme expliquant comment vous avez créé le devoir (-0.1p)
  2. Vous pouvez utiliser seulement les fonctions de lea biblioteques std et nix.
  3. Un devoir qui passe tous les tests automatisés obtiendra 10 sur 10 si vouz ne trichez pas en utilisant un API interdit.

Copier

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.

Questions

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.

NE PUBLIEZ PAS DE CODE SOURCE. Cela est considéré comme copiage et vous aller recevoir 0p pour le devoir.

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.

Rusty Shell

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.

Commandes internes: commandes que le shell exécute: 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:

  • Opérateur de séquençage ;
    • sera utilisé pour exécuter des commandes séquentiellement;
    • par exemple, expr1; expr2 commencera par exécuter les commandes expr1 et les commandes expr2 seulement après l'exécution de expr1;
  • opérateurs d'exécution conditionnelle && et ||
    • seront utilisés pour exécuter des commandes en fonction du code d'erreur;
    • 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.
  • l'opérateur de pipe | 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:

  1. opérateur pipe
  2. opérateurs d'exécution conditionnelle
  3. opérateur de parallélisme (pas utilise)
  4. opérateur de séquençage

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
    • ATTENTION : Le rustyshell doit toujours fonctionner a l'utilisation de la commande cd sans paramètre, remplacer le répertoire en cours par le répertoire home de l'utilisateur courant (variable $HOME)

Le shell doit aussi supporter les sous-commandes:

  • Le format d'utilisation est commande $(commande ou liste commandes)
  • 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

  • Vous n'avez pas besoin d'écrire l'analyseur de ligne de commande, vous pouvez utiliser celui du modèle de devoir.

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:

  1. Lancer des commandes simples ( ls , ls -l )
  2. Exécuter des commandes internes ( cd , exit , quit)
  3. mise en place de redirections (opérateurs < , > , 2> , &> , » , )
  4. séquencement des commandes (opérateurs &&, ||, ;)
  5. implémentation des opérateurs & (parallèle, pas utilise)
  6. |
  • Voici quelques exemples de commandes et le résultat généré par celles-ci:
 $ 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

Documents d'aide

Traitement de la ligne de commande

Pour traiter la ligne de commande, nous avons déjà écrit un analyseur que vous pouvez utiliser.

Pour voir à quoi ressemble la structure de données à partir de l'analyseur, exécutez le modèle et apres introduisez une commande du clavier.

$ cargo run
 
$ ls
Command "ls"
SimpleCommand {
    assignments: [],
    parameters: [
        [
            Word(
                "ls",
            ),
        ],
    ],
    redirects: [],
}
 
$ ls && echo "folder exists"
Command "ls && echo \"folder exists\""
AndCommand(
    SimpleCommand {
        assignments: [],
        parameters: [
            [
                Word(
                    "ls",
                ),
            ],
        ],
        redirects: [],
    },
    SimpleCommand {
        assignments: [],
        parameters: [
            [
                Word(
                    "echo",
                ),
            ],
            [
                Quotes(
                    [
                        [
                            Word(
                                "folder",
                            ),
                        ],
                        [
                            Word(
                                " ",
                            ),
                        ],
                        [
                            Word(
                                "exists",
                            ),
                        ],
                    ],
                ),
            ],
        ],
        redirects: [],
    },
)

La structure afichee en rustyshell

Pour comprendre comment utiliser la structure renvoyée par l'analyseur, exécutez la commande cargo doc –open et examinez le module parser::ast.

sde2/teme/tema_fr_2_rust.txt · Last modified: 2023/03/31 11:41 by alexandru.radovici
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0