This is an old revision of the document!
Scopul acestei teme este realizarea unui shell simplu, compatibil cu sh;
os.open, os.read, os.write, …)os.fork, os.exec si os.waitpid, …)f.write(), os.popen, caz în care nu va fi punctată).Tema se rezolva individual. Orice tentativa de copiere va rezulta in 0p pentru tema respectiva. Vom utiliza si sisteme automate de detectare a copierii. Daca avem dubii, va vom adresa intrebari suplimentare legate de tema.
Daca aveti intrebari legate de tema, va rugam sa scrieti un issue pe repository-ul de github repository cu titlul de forma [mini-shell] <titlul intrebarii voastre>. Aveti nevoie de un cont de github pentru a scrie intrebari.
Daca doriti sa primiti un email cand se pun intrebari noi sau cand apar raspunsuri, accesati github repository si faceti click pe Watch.
Să se implementeze un shell simplu, care suportă execuția de comenzi externe cu argumente multiple, comenzi interne, redirectări, pipe-uri. Shell-ul trebuie să suporte execuția de comenzi compuse, cu oricâți operatori.
cd, pwd, exit …
Comenzi externe: comenzi care sunt de fapt executabile separate: ls, vim, tree, nano, …
Regula este asa: se verifica daca este comanda interna, daca nu, se presupune ca este o comanda externa.
Shell-ul trebuie să suporte următorii operatori de execuție:
;expr1; expr2 va avea ca efect mai întâi execuția comenzilor expr1 și, după terminarea execuției acestora, execuția comenzilor expr2;&expr1 & expr2 va avea ca efect execuția comenzilor expr1 și a comenzilor expr2 în paralel;execv("./my_homework", "command");
&& și ||expr1 && expr2 va avea ca efect execuția comenzilor expr2 doar în cazul în care comenzile expr1 au ca rezultat un cod de eroare 0;expr1 || expr2 va avea ca efect execuția comenzilor expr2 doar în cazul în care comenzile expr1 au ca rezultat un cod de eroare diferit de zero.| este interpus intre doua comenzi. Efectul este redirectionarea a ceea ce scrie pe ecran primul proces
spre ceea ce citeste de la tastatura al doilea proces. De exemplu, expr1 | expr2 va avea ca efect execuția comezilor expr1 cu stdout-ul redirectat în stdin-ul comenzilor expr2;
Prioritatea operatorilor de execuție este, de la cel mai prioritar la cel mai puțin prioritar:
Shell-ul trebuie, de asemenea, să suporte și următorii operatori de redirectare:
< nume_fisier pentru redirectarea intrării standard din fișierul nume_fisier;> nume_fiser pentru redirectarea ieșirii standard în fișierul nume_fisier;2> nume_fisier pentru redirectarea ieșirii de eroare standard în fișierul nume_fisier;&> nume_fisier pentru redirectarea ieșirii standard și ieșirii de eroare standard în fișierul nume_fisier;>> nume_fisier pentru redirectarea ieșirii standard în fișierul nume_fisier în modul append;2>> nume_fisier pentru redirectarea ieșirii de eroare standard în fișierul nume_fisier în modul append.În fine, shell-ul trebuie să suporte următoarele comenzi interne:
exit și quit pentru terminarea shell-uluicd director pentru schimbarea directorului curentcd fără parametru. Nu se impune implementarea comportamentului din bash (schimbarea directorului curent cu directorul home al utilizatorului curent) și nici o valoare de exit pentru acest scenariu (practic, cd fără parametru poate să nu facă nimic, dar să nu rămână cu comportament nedefinit care să ducă la erori).Shell-ul trebuie să suporte subcomenzi:
comanda $(comanda sau lista comenzi)README din arhivă. Exemplu de utilizare a parserului găsiți în sursa cmd.py, care poate fi folosită ca schelet pentru temă.
urmat de un spațiu).cmd.py.Tema este relativ complexa fata de cea anterioara. Un sablon pentru inceperea temei este disponibil in repository in directorul tema3.
Recomandăm rezolvarea și testarea din aproape în aproape a temei, după pași:
ls, ls -l)cd, exit, quit)<, >, 2>, &>, >>, 2>>)&&, ||, ;)& (paralel)|$ 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 > exit
Cursuri utile:
Laboratoare utile:
Resurse:
Pentru parcurgerea linii de comanda, am scris noi deja un parser (parser.py) pe care il puteti folosi.
Incepeti tema in fisierul cmd.py aflat in sablon.
Pentru a vizualiza cum arata structura de date primita de la parser, rulati scriptul din cmd.py după care introduceți o comandă de la tastatură.
pip3 install bashlex --target=.).
$ 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
Prin apelarea parse.parse(line), se va intoarce un obiect de tipul Command.
Proprietati:
$(cmd_list), elementul va fi de tipul Command, in caz contrar, elementul va fi de tipul SimpleCommand
<)>, »)2>, 2», &>, &»)2», &»)», &»)Obiectul de tip SimpleCommand este folosit in cadrul comenzilor cu op egal OP_NONE (comanda simpla). Acestea se gasesc in lista commands si sunt fie comenzi, fie parametrii unor comenzi.
Proprietati:
Modulul parse expune urmatoarele tipuri de operatii (valoarea lui command.op):
cmd1 && cmd2)cmd1 || cmd2)cmd1 ; cmd2)cmd1 & cmd2)comanda parametrii)cmd1 | cmd2)
Pentru a testa tema local, va recomandam ca prima data sa rulati comanda make -f Makefile.checker in directorul devoir3. Astfel se vor instala toate modulele necesare pentru rularea fisierului cmd.py. In continuare, puteti rula tema folosind python3 cmd.py, iar in directorul verify veti gasi toate comenzile pe care tema trebuie sa le ruleze.
a|b|c trebuie sa am 3 forkuri sau pot să am 4 sau 5?$OLDPWD și $PWD), history, multe altele … (vezi man bash pentru o idee despre funcționalitatea unui shell complet args = ["/bin/bash", "-c", command] os.execv(args[0], args);
os.execv pe tema mea pentru a executa o parte din arbore independent?Tema se va incarca pe vmchecker. Logati-va pe site cu folosind utilizatorul de pe moodle, selectati cursul Systemes d'Explotation (FILS) si incarcati arhiva temei.
Fisierul readme are urmatorul format:
Numele vostru intreg Grupa Descrierea rezolvarii temei, de ce ati ales anumite solutii, etc.
Pentru a incarca tema, urmariti pasii:
NU includeti directoarele specifice bibliotecii bashlex (pycache, bashlex, bashlex-0.14.dist-info).
Dupa ce incarcati arhiva, vmchecker va rula:
unzip archive.zip homework cd homework make -f Makefile.checker