-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathb_shell.py
More file actions
executable file
·283 lines (258 loc) · 7.67 KB
/
b_shell.py
File metadata and controls
executable file
·283 lines (258 loc) · 7.67 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
#! /usr/bin/env python3
import subprocess
import signal
import os, sys
import shutil
import time
from datetime import datetime
# ========================
# Run command
# Run an executable somewhere on the path
# Any number of arguments
# ========================
def runCmd(fields):
if(fields[0] == ""):
return
execname = add_path(fields[0])
if(not execname):
print('Executable file ' + str(fields[0]) +' not found')
return
else:
print("Child process:",os.getpid(),"executing from:",execname)
try:
p = os.fork()
if(p == 0):
os.execv(execname, fields)
else:
signal.signal(2, lambda *args: None)
child_pid, status = os.waitpid(0,0)
exit_status = os.WEXITSTATUS(status)
print("\nChild process:", child_pid, "exit code:", exit_status)
except OSError:
print("Unexpected error has occured")
def shellExit():
print("\nKeyboard interrupt: exiting process")
sys.exit(0)
# ========================
# Constructs the full path used to run the external command
# Checks to see if the file is executable
# ========================
def add_path(cmd):
THE_PATH = ["/bin/", "/usr/bin/", "/usr/local/bin/", "./"]
if cmd[0] not in ['/', '.']:
for d in THE_PATH:
execname = d + cmd
if(os.path.isfile(execname) and os.access(execname, os.X_OK)):
return execname
return False
else:
return cmd
def help_cmd():
commands = {"info X:": "check if file/dir X exists", "files:": "displays all files in current directory", "delete X:": "deletes existing files named X", "copy X Y:": "copies an existing file X to a non-existing file Y", "where:":"print working directory", "down D:": "changes to directory D if it exists", "up:":"acesses directory one level closer to the root from currenty directory","finish:":"exists shell script" ,"help:": "you're reading it"}
print("HELP PAGE 1 OF 1")
print("=============================================================================")
count = 1
for entries in commands:
print(str(count) + ".",entries, commands[entries])
count += 1
print("=============================================================================")
# ========================
# files command
# List file and directory names
# No arguments
# ========================
def files_cmd(fields):
if(checkArgs(fields, 0)):
count = 1
if(len(os.listdir('.')) == 0):
print("The current directory is empty")
for filename in os.listdir('.'):
print(str(count)+".",filename)
count += 1
# ========================
# info command
# List file information
# 1 argument: file name
# ========================
def info_cmd(fields):
if(checkArgs(fields, 1)):
filename = str(fields[1])
if(os.path.exists(filename)):
if(os.path.isfile(filename)):
info_helper_printer(True, filename)
else:
info_helper_printer(False, filename)
else:
print("File " + filename + " not found in current directory ")
# ========================
# info command helpers
# info printer - handles the formatting for the file description
# ========================
def info_helper_printer(isFile, filename):
headers = ["Name", "Owner", "Type", "Modification Time"] # column headers
width = [20, 10, 10, 20] # max width of data in each column
details = os.stat(filename)
time = details.st_mtime
time = datetime.fromtimestamp(time).strftime('%b %d %Y %H:%M')
info = []
exe = False
if(isFile):
if(os.access(filename, os.X_OK)): exe = True;
headers.append("Size")
width.append(10)
headers.append("Executable")
width.append(10)
info.append(filename)
info.append(details.st_uid)
info.append("File")
info.append(time)
info.append(details.st_size)
info.append(str(exe))
info_helper_printer_header(width, headers)
info_helper_printer_table(width, info)
else:
info.append(filename)
info.append(details.st_uid)
info.append("Dir")
info.append(time)
info_helper_printer_header(width, headers)
info_helper_printer_table(width, info)
# ========================
# info command helpers
# info printer header - prints header for info
# ========================
def info_helper_printer_header(width,headers):
length = sum(width)
field_num = 0
output = ''
print('-' * length)
while field_num < len(headers):
output += '{field:{fill}<{width}}'.format(field=headers[field_num], fill=' ', width=width[field_num])
field_num += 1
print(output)
print('-' * length)
# ========================
# info command helpers
# info printer header - prints table body for info
# ========================
def info_helper_printer_table(width, info):
fieldNum = 0
output = ''
while fieldNum < len(info):
output += '{field:{fill}<{width}}'.format(field=info[fieldNum], fill=' ', width=width[fieldNum])
fieldNum += 1
print(output)
# ========================
# copy X Y
# copies an existing file X to a non-existing file Y
# 2 arguments
# ========================
def copy_cmd(fields):
if(checkArgs(fields, 2)):
fileA = str(fields[1])
fileB = str(fields[2])
cond1 = os.path.isfile(fileA)
cond2 = os.path.isfile(fileB)
if(cond1 and not cond2):
shutil.copyfile(fileA,fileB)
if(os.path.isfile(fileB)):
"copy successfull"
else:
"error copying"
else:
if(not cond1 and cond2): print("file " + fileA + " not found")
if(cond2): print("file " + fileB + " already exists")
# ========================
# delete
# deletes existing files named X
# 1 arguments
# ========================
def delete_cmd(fields):
if(checkArgs(fields, 1)):
filename = fields[1]
if(os.path.isfile(filename)):
os.unlink(filename)
if(not os.path.isfile(filename)):
print("delete success")
return
print(filename + ": no such file")
# ========================
# where command
# prints current directory
# No arguments
# ========================
def where_cmd(fields):
if(checkArgs(fields, 0)):
print(os.getcwd())
# ========================
# down command
# changes to directory D if it exists
# 1 argument
# ========================
def down_cmd(fields):
if(checkArgs(fields, 1)):
newPath = str(fields[1])
if(os.path.isdir(newPath)):
os.chdir(newPath)
else:
print("specified directory path not found")
# ========================
# up command
# acesses directory one level closer to the root from currenty directory
# 1 argument
# ========================
def up_cmd(fields):
if(checkArgs(fields, 0)):
if(os.getcwd() == "/"):
print("At root level directory /")
else:
os.chdir('..')
# ========================
# exit command
# Exists program
# ========================
def exit_cmd(fields):
print("Terminating program...")
sys.exit(0)
# ----------------------
# Other functions
# ----------------------
def checkArgs(fields, num):
numArgs = len(fields) - 1
if numArgs == num:
return True
if numArgs > num:
print(" Unexpected argument " + fields[num+1] + " for command " + fields[0])
else:
print(" Missing argument for command " + fields[0])
return False
# ----------------------------------------------------------------------------------------------------------------------
while True:
line = ''
try:
line = input("b_Shell>") # NOTE! This is only for python 2. Should be 'input' for python 3
# except KeyboardInterrupt:
# sys.exit('\n Keyboard interrupt: exiting process')
except EOFError:
sys.exit('\n EOFError: exiting process')
fields = line.split()
if(fields[0] == "files"):
files_cmd(fields)
elif(fields[0] == "where"):
where_cmd(fields)
elif(fields[0] == "down"):
down_cmd(fields)
elif(fields[0] == "up"):
up_cmd(fields)
elif(fields[0] == "finish"):
exit_cmd(fields)
elif(fields[0] == "copy"):
copy_cmd(fields)
elif(fields[0] == "delete"):
delete_cmd(fields)
elif(fields[0] == "info"):
info_cmd(fields)
elif(fields[0] == "help"):
help_cmd()
else:
runCmd(fields)