-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmini_shell.py
More file actions
141 lines (115 loc) · 6.6 KB
/
mini_shell.py
File metadata and controls
141 lines (115 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import sys, os
import lexer as ssp
#C1="ps -aux | sort -k1n 2>> /dev/null | tr 'a-z' 'A-Z' | tee toto.txt | cat > log.txt "
#C1="ps -aux | sort -k1n | wc -l"
print("******************* PROGRAMME MINI-SHELL *******************\n")
print("\t")
#result = ssp.get_parser().parse(C1)
#def execpipe(inp,output,command):
def executerLesPipes(rfd,wfd,command): # fonction permet d'executer une commande à en lecture ds le rfd et ecrire vers wfd
pid = os.fork()
if pid == 0: # le fils s'occope de l'execution des commandes
commande=command._cmd.getCommand() # pour recuperer les commandes à partir de l'objet PROCESS du lexer
argCommande=command._cmd.getArgs()
argCommande = [commande]+argCommande # on rajoute la commande en premier puis l'argument : toute les fn exec le 1er arg est la commande lui meme
if rfd != 0: # on verifie si il y a lecture venant de l'entrer standard
os.dup2(rfd,0)# on lu depuis rfd au lieu de l'entrer standard
os.close(rfd)# on fermer apres
else:
redirEntree = filtrerRedirectionsEntree(command) # on cherche si il y a une redirection dans la commande
if redirEntree:
re = os.open(redirEntree._filespec, os.O_RDONLY)
os.dup2(re, 0)
os.close(re)
if wfd != 1: # si on a une sortie vers le tube
os.dup2(wfd,1) # au lieu de la sortie standard au ecrit vers wfd
os.close(wfd) # on ferme
else :
redirSortie = filtrerRedirectionsSortie(command) # on cherche si on a une redirection de sortie dans la commande
if redirSortie:
re_wr_fd = None # on initialise
if redirSortie.isAppend(): # si c'est en mode Append on ouvre en mode append
re_wr_fd=os.open(redirSortie._filespec, os.O_WRONLY | os.O_APPEND | os.O_CREAT )
else: # sinon on fait une redirection normale
re_wr_fd=os.open(redirSortie._filespec, os.O_WRONLY| os.O_CREAT | os.O_TRUNC)
os.dup2(re_wr_fd, 1)
os.close(re_wr_fd)
redirErreur=filtrerRedirectionsErreur(command)# redirection d'erreur gerer par le fils
if redirErreur:
re_Er_fd = None
if redirErreur.isAppend():
re_Er_fd=os.open(redirErreur._filespec, os.O_WRONLY | os.O_APPEND | os.O_CREAT)
else:
re_Er_fd=os.open(redirErreur._filespec, os.O_WRONLY| os.O_CREAT | os.O_TRUNC)
os.dup2(re_Er_fd,2)
os.close(re_Er_fd)
try:
os.execvp(commande,argCommande)
except Exception as e:
os.write(2,bytearray("Il y a un probleme avec l'execution de " +commande +"\n","utf-8"))
sys.exit(-1)
else: # le père attend la mort du fils
os.waitpid(pid, 0)
def executer(p): # p c'est l'objet process cette permet d'executer la commande
rfd = 0
for i in p:
r,w = os.pipe()
executerLesPipes(rfd,w,i)
os.close(w)
rfd = r # entrer du tube courant et rfd entree du tube precedent
pid = os.fork()
if pid == 0:
if rfd != 0:
os.dup2(rfd,0)
dernierCommande = p[-1]._cmd.getCommand() # on prend la dernière commande la chaine et on execute
dernierArgs = p[-1]._cmd.getArgs() # on prend dernier argument
dernierArgs = [dernierCommande] + dernierArgs
redirSortie = filtrerRedirectionsSortie(p[-1]) # on redirige la derniere commande vers la sortie
if redirSortie:
re_wr_fd = None
if redirSortie.isAppend():
re_wr_fd=os.open(redirSortie._filespec, os.O_WRONLY | os.O_APPEND | os.O_CREAT )
else:
re_wr_fd=os.open(redirSortie._filespec, os.O_WRONLY| os.O_CREAT | os.O_TRUNC)
os.dup2(re_wr_fd, 1)
os.close(re_wr_fd)
""" Partie pour faire la redirection d'erreur """
redirErreur=filtrerRedirectionsErreur(p[-1])# redirection d'erreur gerer par le fils
if redirErreur:
re_Er_fd = None
if redirErreur.isAppend():
re_Er_fd=os.open(redirErreur._filespec, os.O_WRONLY | os.O_APPEND | os.O_CREAT)
else:
re_Er_fd=os.open(redirErreur._filespec, os.O_WRONLY| os.O_CREAT | os.O_TRUNC)
os.dup2(re_Er_fd,2)
os.close(re_Er_fd)
try:
os.execvp(dernierCommande, dernierArgs)
except Exception as e:
os.write(2,bytearray("Il y a un probleme avec l'execution de " + dernierCommande +"\n","utf-8"))
sys.exit(-1)
os.wait()
return
"""********************** Fin redirection erreur ************************************** """
""" filtrer la redirection d'entree à partir d'un Processus """
def filtrerRedirectionsEntree(processus): # procesus c'est un obet de la class PROCESS(): du lexer.py
if not processus._redirs or not processus._redirs._redirs : # si il n'y pas de redirection renvoi None
return None
return next((re for re in processus._redirs._redirs if re.__class__.__name__ == "INREDIR"), None) # return la 1ere valeur dans une liste qui valide une condition, si aucun elt ne valid la condition le 2 arg est renvoyer
""" filtrer la redirection sortie à partir d'un Processus """
def filtrerRedirectionsSortie(processus):
if not processus._redirs or not processus._redirs._redirs:
return None
return next((re for re in processus._redirs._redirs if re.__class__.__name__ == "OUTREDIR"), None)
""" filtrer la redirection erreur à partir d'un Processus """
def filtrerRedirectionsErreur(processus):
return next((re for re in processus._redirs._redirs if re.__class__.__name__ == "ERRREDIR"), None)
# ******************************Fin *************************************
""" fonction Principale """
#print(commandes)
while(True): # on fait une boucle infini pour excuter des commande à partir du prompt
C = input("\nlinux$")
if C.strip()=="": # si il n'y a une ligne vide ou space passe et continue avec pour retourner à l'etape 1
continue
TableauCommande = ssp.get_parser().parse(C)
executer(TableauCommande)