zoukankan      html  css  js  c++  java
  • 实现简易版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
    ",1900+tp->tm_year);//必须加上1900,返回的值并不是完整的年份,比真实值少了1900
    101 }
    102 void welcome(){
    103     //如下是欢迎信息
    104     //为了是程序更友好,加入了颜色
    105     //颜色是紫色,背景色与shell相同
    106     printf("e[32mwelcome to myshelle[0m
    ");
    107     printf("e[32mit's a Lunix-like shell program made by use[0m
    ");
    108     printf("e[32mhope you have a good time with it :-)e[0m
    ");
    109 }
    110 void mypwd(){
    111     char pathname[MAX_PATH_LEN];
    112     if(getcwd(pathname,MAX_PATH_LEN)){//获取路径名
    113         printf("%s
    ",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!
    ");
    123     sleep(1);//暂停1s,看上去视觉效果好一些
    124     exit(0);
    125 }
    126 void exit(){
    127    exit(0);
    128 }
    129 void myclr(){
    130     cout << "33[2J";
    131     cout << "33[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<<'	';
    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<<'	'; //group name
    254           cout << st.st_size<<'	';  //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()) != '
    ')
    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
    ");
    299     printf("the following are the BUILT-IN commands supported by myshell
    ");
    300     printf("
    ");
    301 
    302     printf("exit:      exit                            quit the shell directly
    ");
    303     printf("clr:       clr                             clear the screen
    ");
    304     printf("time:      time                            show the current time in an elegant format
    ");
    305     printf("myshell:   myshell [filename]              execute a batchfile
    ");
    306     printf("quit:      quit                            quit the shell with thank-you
    ");
    307     printf("pwd:       pwd                             print the current working directory
    ");
    308     printf("help:      help/help [command]             show the manual of help/get help info of a sepcified command
    ");
    309 
    310 }
    311 void print_cmdinfo(string cmdname){
    312 
    313      if(cmdname=="exit"){
    314         printf("usage:quit the shell directly
    ");
    315         printf("options            descriptions
    ");
    316         printf("none               see the manual,plz
    ");
    317     }
    318     else if(cmdname=="pwd"){
    319         printf("usage:print the current working directory
    ");
    320         printf("options            descriptions
    ");
    321         printf("none               see the manual,plz
    ");
    322     }
    323     else if(cmdname=="time"){
    324         printf("usage:show the current time in an elegant format
    ");
    325         printf("options            descriptions
    ");
    326         printf("none               see the manual,plz
    ");
    327     }
    328     else if(cmdname=="clr"){
    329         printf("usage:clear screen
    ");
    330         printf("options            descriptions
    ");
    331         printf("none               see the manual,pls
    ");
    332     }
    333     else if(cmdname=="myshell"){
    334         printf("usage:execute a batchfile
    ");
    335         printf("options            descriptions
    ");
    336         printf("none               see the manual,plz
    ");
    337     }
    338     else if(cmdname=="help"){
    339         printf("usage:show the manual of help/get help info of a sepcified command
    ");
    340         printf("options            descriptions
    ");
    341         printf("none               see the manual,plz
    ");
    342     }
    343     else if(cmdname=="quit"){
    344         printf("usage:quit the shell with thank-you information
    ");
    345         printf("options            descriptions
    ");
    346         printf("none               see the manual,plz
    ");
    347     }
    348     else {//如果有错
    349         printf("myshell: help: Invalid use of help command
    ");//打印提示信息
    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

  • 相关阅读:
    Linux权限及归属管理
    Linux账户管理
    随笔记录 磁盘坏道故障 2019.8.7
    随笔记录 MBR扇区故障系统备份与还原 2019.8.7
    随笔记录 grub引导故障修复 2019.8.7
    随笔记录 综合训练 2019.8.5
    随笔记录 磁盘配额2019.8.2
    随笔记录 2019.7.31
    随笔记录 2019.7.31
    随笔记录 linux命令 2019.7.29
  • 原文地址:https://www.cnblogs.com/henuliulei/p/10034008.html
Copyright © 2011-2022 走看看