1. 程式人生 > >【Linux】實現一個 mini_shell

【Linux】實現一個 mini_shell

在學習了程序等待和程式替換及其相關函式之後,就可以實現一個我們自己簡單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 }

進行一下功能檢驗:

一些簡單的基本命令都可以完成!