0
点赞
收藏
分享

微信扫一扫

实现简易版shell

一葉_code 2022-06-28 阅读 52

操作系统小组作业,实现一个简易shell,shell实现了下列命令

exit------退出终端命令

clr-------清屏命令

time-----时间命令

myshell----欢迎命令

quit-----终止命令

pwd-----路径命令

cat-----查看文件命令

help---帮助命令

help [参数]---查看某个具体的命令的注释

ls -l-----查看目录下的文件命令

只实现了简单的几个命令,仅做参考,代码如下

1 #include<bits/stdc++.h>
2 #include<unistd.h>
3 #include<stdio.h>
4 #include<sys/types.h>
5 #include<pwd.h>
6 #include<time.h>
7 #include<dirent.h>
8 #include<stdlib.h>
9 #include<sys/stat.h>
10 #include<fcntl.h>
11 #include <grp.h>
12 #include <sys/wait.h>
13 #include<memory.h>
14 using namespace std;
15 #define MAX_LINE 80
16 #define MAX_NAME_LEN 50
17 #define MAX_PATH_LEN 1000
18 int cmd_cnt;
19 char *cmd_array[MAX_LINE/2+1];
20 string st;
21 void mytime(){
22 int weekday;
23 int month;
24 time_t tvar;
25 struct tm *tp;
26 time(&tvar);
27 tp=localtime(&tvar);//获取本地时间
28 weekday=tp->tm_wday;
29 switch(weekday){//根据不同的值打印不同的星期
30 case 1:
31 printf("Mon ");
32 break;
33 case 2:
34 printf("Tues ");
35 break;
36 case 3:
37 printf("Wed ");
38 break;
39 case 4:
40 printf("Thur ");
41 break;
42 case 5:
43 printf("Fri ");
44 break;
45 case 6:
46 printf("Sat ");
47 break;
48 case 7:
49 printf("Sun ");
50 break;
51 default:
52 break;
53 }
54 month=1+tp->tm_mon;//必须要加1,经过查阅资料:tm_mon比实际的值少了1
55 switch(month){//根据不同的值打印月份名
56 case 1:
57 printf("Jan ");
58 break;
59 case 2:
60 printf("Feb ");
61 break;
62 case 3:
63 printf("Mar ");
64 break;
65 case 4:
66 printf("Apr ");
67 break;
68 case 5:
69 printf("May ");
70 break;
71 case 6:
72 printf("Jun ");
73 break;
74 case 7:
75 printf("Jul ");
76 break;
77 case 8:
78 printf("Aug ");
79 break;
80 case 9:
81 printf("Sep ");
82 break;
83 case 10:
84 printf("Oct ");
85 break;
86 case 11:
87 printf("Nov ");
88 break;
89 case 12:
90 printf("Dec ");
91 break;
92 default:
93 break;
94 }
95 printf("%d ",tp->tm_mday);//日期
96 printf("%d:",tp->tm_hour);//小时
97 printf("%d:",tp->tm_min);//分钟
98 printf("%d ",tp->tm_sec);//秒
99 printf("CST ");//CST,意思是China Standard Time
100 printf("%d\n",1900+tp->tm_year);//必须加上1900,返回的值并不是完整的年份,比真实值少了1900
101 }
102 void welcome(){
103 //如下是欢迎信息
104 //为了是程序更友好,加入了颜色
105 //颜色是紫色,背景色与shell相同
106 printf("\e[32mwelcome to myshell\e[0m\n");
107 printf("\e[32mit's a Lunix-like shell program made by us\e[0m\n");
108 printf("\e[32mhope you have a good time with it :-)\e[0m\n");
109 }
110 void mypwd(){
111 char pathname[MAX_PATH_LEN];
112 if(getcwd(pathname,MAX_PATH_LEN)){//获取路径名
113 printf("%s\n",pathname);
114 }
115 else{//如果出错
116 perror("myshell: getcwd");//报错
117 exit(1);
118 }
119 }
120
121 void myquit(){
122 printf("Thanks for your using,bye-bye!\n");
123 sleep(1);//暂停1s,看上去视觉效果好一些
124 exit(0);
125 }
126 void exit(){
127 exit(0);
128 }
129 void myclr(){
130 cout << "\033[2J";
131 cout << "\033[H";
132
133 }
134
135 void printprompt(){//实现命令提示符
136
137 char hostname[MAX_NAME_LEN];
138 char pathname[MAX_PATH_LEN];
139 struct passwd *pwd;
140 pwd=getpwuid(getuid());
141 gethostname(hostname,MAX_NAME_LEN);
142 printf("\e[34m%s@%s:\e[0m",pwd->pw_name,hostname);
143
144 printf("$");
145
146
147 }
148
149
150 //*****************************************************获得文件权限属性
151 void getPower(mode_t mod)
152 {
153 for(int n=8; n>=0; n--)
154 {
155 if(mod&(1<<n))//移位运算,1左移位n位
156 {
157 switch(n%3)
158 {
159 case 2:
160 printf("r");
161 break;
162 case 1:
163 printf("w");
164 break;
165 case 0:
166 printf("x");
167 break;
168 default:
169 break;
170 }
171 }
172 else
173 {
174 printf("-");
175 }
176 }
177 }
178
179
180
181 void cat(string filename){
182 ifstream fin( filename);
183 char str[200];
184 while ( fin.getline(str,200) )
185 {
186 cout << str << endl;
187 }
188 }
189
190
191
192
193 void ls(string allstr,string substr){
194
195 /******************************ls*************************
196 *
197 *dirName[] :store single filename
198 *dir :point to currnt directory
199 *rent :指针变量
200 *st :文件基本操作
201 **********************************************************/
202
203
204 struct stat st;
205 char dirName[100];
206
207 DIR *dir;
208 struct dirent *rent;//struct
209 dir = opendir(".");
210
211
212 if(allstr== "ls"){
213
214 if(dir != NULL)
215 {
216 while((rent=readdir(dir)))
217 {
218
219 strcpy(dirName,rent->d_name);
220 if (dirName[0]!='.' && dirName)
221 {
222 cout << dirName<<'\t';
223 }
224 }
225 }
226
227 cout << endl;
228 }
229 else if(dir == NULL)
230 {
231 cout << "*****empty*****"<<endl;
232 }
233 else if(allstr != "ls -l")
234 {
235 cout << substr+": "+ "unrecognized option "+"'"+allstr.substr(substr.length())+"'"<<endl;
236 cout << "Try 'ls -l' "<<endl;
237 }
238
239 /******************************************ls -l*************************/
240
241 else if(allstr == "ls -l")
242 {
243 while( rent = readdir(dir) )
244 {
245 strcpy(dirName,rent->d_name);
246 if (dirName[0]!='.' && dirName)
247 {
248 if(-1 != stat(rent->d_name, &st) )//get fileInfomation from filename p->d_name and save it in structure stat
249 {
250 getPower(st.st_mode); //get r-w-d
251 cout <<" "<<st.st_nlink<<" ";//get number of file links
252 cout <<" "<<getpwuid(st.st_uid)->pw_name<<" ";//owner name
253 cout <<getgrgid(st.st_gid)->gr_name<<'\t'; //group name
254 cout << st.st_size<<'\t'; //get total size , in bytes
255
256 //printf 12 char and align = left
257 printf("%.12s ",4+ctime(&st.st_mtime)); //the last time of changing file
258 cout << dirName;
259 cout << endl;
260 }
261 }
262 }
263 }
264
265 closedir(dir);
266 }
267
268
269
270
271 //****************************************************获得输入字符
272 string strInput()
273 {
274 string str;
275 string res;
276 char c;
277 while( (c = getchar()) != '\n')
278 str += c;
279
280 vector<string> arr;
281 istringstream istr(str);
282 string word;
283 while(istr>>word) {
284 arr.push_back(word);//添加元素到尾部
285 }
286
287 for(int i=0; i<arr.size(); i++) {
288 if(i != arr.size() - 1)
289 res += arr[i]+" ";
290 else
291 res += arr[i];
292 }
293
294 return res;
295 }
296 ///////////////////////////////////////////////////////////help命令
297 void print_manual(){
298 printf("welcome to the manual of myshell, hope it's useful for you\n");
299 printf("the following are the BUILT-IN commands supported by myshell\n");
300 printf("\n");
301
302 printf("exit: exit quit the shell directly\n");
303 printf("clr: clr clear the screen\n");
304 printf("time: time show the current time in an elegant format\n");
305 printf("myshell: myshell [filename] execute a batchfile\n");
306 printf("quit: quit quit the shell with thank-you\n");
307 printf("pwd: pwd print the current working directory\n");
308 printf("help: help/help [command] show the manual of help/get help info of a sepcified command\n");
309
310 }
311 void print_cmdinfo(string cmdname){
312
313 if(cmdname=="exit"){
314 printf("usage:quit the shell directly\n");
315 printf("options descriptions\n");
316 printf("none see the manual,plz\n");
317 }
318 else if(cmdname=="pwd"){
319 printf("usage:print the current working directory\n");
320 printf("options descriptions\n");
321 printf("none see the manual,plz\n");
322 }
323 else if(cmdname=="time"){
324 printf("usage:show the current time in an elegant format\n");
325 printf("options descriptions\n");
326 printf("none see the manual,plz\n");
327 }
328 else if(cmdname=="clr"){
329 printf("usage:clear screen\n");
330 printf("options descriptions\n");
331 printf("none see the manual,pls\n");
332 }
333 else if(cmdname=="myshell"){
334 printf("usage:execute a batchfile\n");
335 printf("options descriptions\n");
336 printf("none see the manual,plz\n");
337 }
338 else if(cmdname=="help"){
339 printf("usage:show the manual of help/get help info of a sepcified command\n");
340 printf("options descriptions\n");
341 printf("none see the manual,plz\n");
342 }
343 else if(cmdname=="quit"){
344 printf("usage:quit the shell with thank-you information\n");
345 printf("options descriptions\n");
346 printf("none see the manual,plz\n");
347 }
348 else {//如果有错
349 printf("myshell: help: Invalid use of help command\n");//打印提示信息
350 }
351
352 }
353 void myhelp(){
354 if(cmd_cnt==1){//如果是不带参数的help
355 print_manual();//调用子函数print_manual打印用户帮助手册
356 }
357 else if(cmd_cnt==2){//如果格式是"help [command]"
358 print_cmdinfo(st);//打印单个命令的帮助信息
359 }
360
361 }
362 void help(string str){
363 if(str=="help"){
364 cmd_cnt=1;
365 }
366 else if(str.length()>5){
367
368 cmd_cnt=2;
369 st=str.substr(5,str.length());
370 }
371
372 myhelp();
373 }
374 /////////////////////////////////////////////////////////////////////////////////
375 int main()
376 {
377 string n;
378 string str1; //first str !=include space
379 string str2;
380
381
382 while(true){
383 printprompt();
384 n=strInput();
385
386 istringstream istr(n);
387 istr >> str1>>str2;
388
389 if(str1 == "ls"){
390 ls(n,str1);
391 continue;
392 }
393 if(n=="exit")//退出
394 exit();
395 else if(n=="clr"){
396 myclr();
397 }
398 else if(n=="time")
399 {
400 mytime();
401 }
402 else if(n=="myshell")
403 {
404 welcome();
405 }
406 else if(n=="quit")
407 {
408 myquit();
409 }
410 else if(n=="pwd")
411 {
412 mypwd();
413 }
414 else if(str1 == "cat"){
415 cat(str2);
416 }
417 else if(str1=="help"){
418 help(n);
419 }
420 else
421 cout << "invaild command" << endl;
422
423 }
424
425 return 0;
426 }

如果需要的话,下面链接里面有我对该代码的部分不常见的函数和结构体的注释,如需要的可以看一下

作者:你的雷哥

本文版权归作者所有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。

举报

相关推荐

0 条评论