实现简易版shell

操作系统小组作业,布置的实现一个简易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 }

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

https://files-cdn.cnblogs.com/files/henuliulei/shellzhushi.zip

猜你喜欢

转载自www.cnblogs.com/henuliulei/p/10034008.html