1. 程式人生 > >通過獲取子程序建立的一個迷你版的

通過獲取子程序建立的一個迷你版的

整個程式執行分為四部分:

    1. 寫一個shell的入口,用於提示要輸入資訊
    1. scanf接收一個輸入資訊
    1. 建立子程序
    1. 程式替換
      輸入資訊:
printf("minishell: ");
       fflush(stdout);
       char cmd[1024] = {0};
          if (scanf("%[^\n]%*c", cmd) != 1) {
           getchar();
       }

^\n:scanf本身是遇到空格就要獲取一次,這樣的話就無法獲取
到一個完整的命令,因此‘%[^\n]’表示的是獲取資料直到遇到\n為止
%*c:將緩衝區中的字元都取出來,但是不要它,直接丟掉
目的是為了將最後的\n從緩衝區取出來,防止陷入死迴圈
解析獲得的命令:

在char *ptr = cmd;
        char *argv[32] = {NULL};
        int argc = 0;
        argv[argc++] = ptr;
        while(*ptr != '\0') {
       	  int isspace(int c);
            //用於判斷一個字元是否是:\t \n \r 空格 
            //解析一個字串時候這裡就是對空格的判斷
            if (isspace(*ptr)) {
                while(isspace(*ptr) && *ptr != '\0') {
                    *ptr++ = '\0';
                }
                argv[argc++] = ptr;
            }
            ptr++;
        }
        if  (fork() == 0) {
            execvp(argv[0], argv);
        }

子程序建立程式替換:

 if  (fork() == 0) {
            execvp(argv[0], argv);
        }
               wait(NULL);
              

需要等待的原因:
1. 避免產生殭屍子程序
2. 是為了等待子程序執行完畢,讓程式邏輯更加完善
完整版程式實現如下:

int main()
{
    while(1) {
        printf("minishell: ");
        fflush(stdout);
        char cmd[1024] = {0};
             if (scanf("%[^\n]%*c", cmd) != 1) {
            getchar();
        }

        char *ptr = cmd;
        char *argv[32] = {NULL};
        int argc = 0;
        argv[argc++] = ptr;
        while(*ptr != '\0') {
                     if (isspace(*ptr)) {
                while(isspace(*ptr) && *ptr != '\0') {
                    *ptr++ = '\0';
                }
                argv[argc++] = ptr;
            }
            ptr++;
        }
        if  (fork() == 0) {
            execvp(argv[0], argv);
        }
             wait(NULL);
       
    }
    return 0;
}