實現一個簡單的shell
阿新 • • 發佈:2018-11-11
程式碼的詳細解釋都在裡面了~~~~
//自己實現一個簡單的shell #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<errno.h> #include<string.h> //1:獲取終端輸入(scanf接收一個輸入資訊) //2:解析輸入(按空格解析到一個一個的命令引數) //3:建立一個子程序:在子程序中級進行程式替換,讓子程序執行命令 //4:等待子程序執行完畢,收屍,獲取退出狀態碼 int argc; char *argv[32]; int param_parse(char *buff) { if(buff == NULL) return -1; char *ptr = buff; char *tmp = ptr; int argc = 0; while((*ptr) != '\0') { if(isspace(*ptr))//判斷是否為: 空格 /f /n /r /t /v { //如果返回值為真,且不是回車‘\0’(沒有結束) //將空格置為‘\0’ //使用argv[argc]來儲存這個字串位置 //迴圈,直到返回值為假或者結束 //解決l -s (多空格無法識別的問題) while(isspace(*ptr) && *ptr != '\0') { *ptr++ = '\0'; } argv[argc++] = tmp; tmp = ptr; } ptr++; } argv[argc++] = tmp; argv[argc] = NULL; return 0; } int do_exec() { int pid = 0; pid = fork(); if(pid < 0) { perror("fork"); return -1; } else if (pid == 0) { execvp(argv[0],argv); exit(0); } //父程序在這裡必須等待子程序退出,來觀察子程序為什麼會退出 //是否出現了什麼錯誤,通過獲取狀態碼,並且轉換退出碼所對應 //的錯誤資訊進行列印 int statu; wait(&statu); //判斷子程序是否程式碼執行完畢退出 if(WIFEXITED(statu)) { //獲取到子程序的退出碼,轉換為文字資訊 printf("%s",strerror(WEXITSTATUS(statu))); } return 0; } int main() { while(1) { printf("shell> "); fflush(stdout); char buff[1024] = {0}; if(scanf("%[^\n]%*c",buff) ==2) //scanf回車代表結束 { getchar();//獲取一個回車,防止直接回車出現的死迴圈 } //scanf本身遇見空格就要獲取一次,這樣就無法獲取完整命令 //%[^\n]:獲取資料直到遇見\n為止 //%*c 清空緩衝區,資料都不要(不然還存有是上一個\n) //從緩衝區取出,直接丟掉。防止回車死迴圈 printf("%s\n",buff); param_parse(buff); do_exec(); } return 0; }