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()
, 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 variabile de mediu:
$VARIABILA_DE_MEDIU
NUME_VARIABILA=valoare
valoare
conține referiri la alte variabile de mediuREADME
din arhivă. Exemplu de utilizare a parserului găsiți în sursa cmd.py
, care poate fi folosită ca schelet pentru temă.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 $ LETTER=alfa && echo $LETTER alfa > echo a > test ; echo b >> test && cat test a b > 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 --target=. bashlex $ 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
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