操作系统"UNIX外壳项目":简易命令行实现(执行命令+历史功能)

运行环境Ubuntu-Linux

代码如下  1 #include <unistd.h>  2 #include <string.h>

  1 #include <unistd.h>
  2 #include <string.h>
  3 #include <stdio.h>
  4 #include <wait.h>
  5 #include <stdlib.h>
  6 #define MAX_LINE 80
  7 typedef struct hst{
  8     int number;
  9     char *hst_cmd[MAX_LINE/2 + 1];
 10     int len;
 11     struct hst *next;
 12 
 13 }HstList;
 14 void outHst(HstList *p);
 15 void reLoad(int n, char *a[], HstList *p, int *num);
 16 int main(void){
 17     char *args[MAX_LINE/2 + 1];
 18     int should_run = 1;
 19     int waitFlag = 1;//flag of wait, 1 represent the father need to wait
 20     int retype = 0;//flag of retype command
 21     int hst_num = 1;//init the HstList
 22     HstList *head, *node, *end, *latest;
 23     head = (HstList*)malloc(sizeof(HstList));
 24     head->number = 0;
 25     end = head;
 26     latest = head;
 27     end->next = NULL;
 28 
 29     while(should_run){
 30         usleep(100000);
 31         printf("myCommand(input 'exit' to exit)>>");
 32         fflush(stdout);
 33         
 34         //read every input
 35         int num = 0;
 36         while(1){
 37             char *tmp = (char*)malloc(50*sizeof(char));
 38             if((scanf("%s", tmp)) == EOF || getchar() == '\n'){
 39                 args[num] = tmp;
 40                 if(strcmp(args[num], "!!") == 0){
 41                     if(latest->number == 0) printf("***you have not input any command recently!***:(\n");
 42                     else{
 43                         reLoad(end->number, args, head, &num);
 44                         break;
 45                     }
 46                     retype = 1;
 47                     break;
 48                 }
 49                 if(args[num][0] == '!' && args[num][1] != '!'){
 50                     char *n = &args[num][1];
 51                     int index = atoi(n);
 52                     if( index < head->number || index > end->number) printf("***the command not found!***:(\n");
 53                     else{
 54                         reLoad(index, args, head, &num);
 55                         break;
 56                     }
 57                     retype = 1;
 58                     break;
 59                 }
 60 
 61                 if(strcmp(args[num], "history") == 0){
 62                     if(latest->number == 0) printf("***you have not input any command!***:(\n");
 63                     else{
 64                         while(latest != NULL){
 65                             outHst(latest);
 66                             latest = latest->next;
 67                         }
 68                         latest = head->next;//when it print out the history, it should be reset
 69                     }
 70                     retype = 1;
 71                     break;
 72                 }
 73                 if(strcmp(args[num], "&") == 0){
 74                     args[num] = NULL;
 75                     waitFlag = 0;
 76                     break;
 77                 }
 78                 if(strcmp(args[num], "exit") == 0){//set the flag of end
 79                     should_run = 0;
 80                     break;
 81                 }
 82                 args[++num] = NULL;//the end of args should be NULL
 83                 break;
 84             }//for delay to close input
 85             args[num] = tmp;
 86             num++;
 87         }
 88         if(retype == 1){
 89             retype = 0;
 90             continue;
 91         }
 92         if(should_run == 0) break;//stop run
 93 
 94         //put the command into history
 95         node = (HstList*)malloc(sizeof(HstList));
 96         end->next = node;
 97         end = node;
 98         end->next = NULL;
 99         node->number = hst_num;
100         node->len = num;
101         hst_num++;
102         for(int i = 0;i <= node->number;i++) node->hst_cmd[i] = args[i];
103         int i;
104         latest = head;
105         for(i = 0;i < 10;i++){
106             if((end->number - i) > 1) continue;
107                    else{
108                        latest = head->next;
109                 break;
110             }
111         }
112         if(i == 10)//latest point to the latest 10 history command
113             while(latest->number != (end->number - 9))
114                 latest = latest->next;
115 
116         //fork a process and insert a program into it
117         int pid;
118         pid = fork();
119         if(pid < 0){
120             printf("***process creation failed!***:(\n");
121         }
122         else if(pid == 0){
123                execvp(args[0], args);
124                printf("***command execution failed!***:(\n");//if the command execute successfully,there will not be returned value, or error occurred
125                exit(1);
126         }
127         else{
128             if(waitFlag == 1){
129                        while(wait(NULL) != pid);//not continue untill recycle the latest child
130             }
131             waitFlag = 1;
132             printf("***parent program finished!***:)\n");
133         }
134         
135     }
136     return 0;
137 }
138 
139 void outHst(HstList *p){
140     printf("%d  ", p->number);
141     for(int i = 0;i < p->len;i++)
142         printf("%s ", p->hst_cmd[i]);
143     printf("\n");
144 }
145 void reLoad(int n, char *a[], HstList *p, int *num){
146     while(p->number != n) p = p->next;
147     for(int i = 0;i <= p->len;i++){
148         a[i] = p->hst_cmd[i];
149     }
150     *num = p->len;
151 }

 

posted @ 2023-03-23 15:55  Bai_huasheng  阅读(52)  评论(0编辑  收藏  举报