【Linux】實現一個 mini_shell
阿新 • • 發佈:2019-01-13
在學習了程序等待和程式替換及其相關函式之後,就可以實現一個我們自己簡單mini_shell了。
shell及其執行原理:
https://blog.csdn.net/Miss_Monster/article/details/86370076
shell工作的基本過程
1.讀取使用者由鍵盤輸入的命令列。
2.分析命令,以命令名作為檔名,並將其它引數改造為系統呼叫execve( )內部處理所要求的形式。
3.終端程序呼叫fork( )建立一個子程序。
4.終端程序本身呼叫wait4()來等待子程序完成(如果是後臺命令,則不等待)。當子程序執行時呼叫execve(),子程序根據檔名到目錄中查詢有關檔案,調入記憶體,執行這個程式。
5.如果命令末尾有&,則終端程序不用執行系統呼叫wait4(),立即發提示符,讓使用者輸入下一條命令;否則終端程序會一直等待,當子程序完成工作後,向父程序報告,此時中斷程序醒來,作必要的判別工作後,終端發出命令提示符,重複上述處理過程。
知道了基本工作原理過程,我們來實現一個簡易的shell。
為了與原本系統的命令列提示符進行區分,我們把原來的 [[email protected] mini_shell]$ 改為我們自己的[[email protected] zh]# 下面是具體程式碼實現及程式碼解釋:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #define MAX 1024 5 #define NUM 32 6 int main() 7 { 8 char* myargv[NUM];//字串拆分後,一個個放進NUM 9 char cmd[MAX];//設定緩衝區大小 10 11 for(;;) 12 { 13 printf("[
[email protected] zh]# ");//printf不加\n,表示訊息不回立即顯示,會被放進緩衝區 14 fflush(stdout); //重新整理緩衝區,輸出printf的內容 15 fgets(cmd,MAX,stdin);//從標準輸入中讀取一行 16 cmd[strlen(cmd)-1]=0; //將\n改為0,取消多餘的空行 17 //ls -a -b -c -d 18 int i = 0; 19 myargv[i]=strtok(cmd," "); 20 i++; 21 while(1) //迴圈執行 22 { 23 char* p=strtok(NULL," ");//字串拆分函式 24 if(p==NULL)//後面沒有子串,則退出 25 { 26 myargv[i]=NULL; 27 break; 28 } 29 myargv[i]=p;//呼叫字串拆分函式 30 i++; 31 }//到此命令列引數解釋完畢 32 pid_t id =fork();//fork建立子程序可以使mini_shell一直執行 33 if(id<0) 34 { 35 36 }else if(id==0) 37 {//child 38 execvp(myargv[0],myargv);/呼叫替換函式將程式和執行命令替換 39 }else{ 40 waitpid(id,NULL,0);//父程序等待子程序執行完畢 41 } 42 } 43 // for(i=0;myargv[i]!=NULL;i++) 44 //{ 45 // printf("%d:%s\n",i,myargv[i]); 46 // } 47 return 0; 48 }
進行一下功能檢驗:
一些簡單的基本命令都可以完成!