20165322 第七周 mybash 的實現
阿新 • • 發佈:2018-11-25
全部 pwd 狀態 order 測試 pty 根據 部分 str
mybash的實現
要求
- 使用fork,exec,wait實現mybash
- 寫出偽代碼,產品代碼和測試代碼
- 發表知識理解,實現過程和問題解決的博客
相關函數的作用
- fork
- fork()函數通過系統調用創建一個與原來進程(父進程)幾乎完全相同的進程(子進程是父進程的副本,它將獲得父進程數據空間、堆、棧等資源的副本。註意,子進程持有的是上述存儲空間的“副本”,這意味著父子進程不共享這些存儲空間。linux將復制父進程的地址空間內容給子進程,因此,子進程由了獨立的地址空間。),也就是這兩個進程做完全相同的事。
- 在父進程中,fork返回新創建子進程的進程ID;
- 在子進程中,fork返回0;
- 如果出現錯誤,fork返回一個負值
- exec
- exec函數族可以根據指定的文件名或目錄名找到可執行文件,並用它來取代原調用進程的數據段、代碼段和堆棧段。在執行完後,原調用進程的內容除了進程號外,其它全部被新程序的內容替換了。另外,這裏的可執行文件既可以是二進制文件,也可以是Linux下任何可執行腳本文件。
- exec函數族可以根據指定的文件名或目錄名找到可執行文件,並用它來取代原調用進程的數據段、代碼段和堆棧段。在執行完後,原調用進程的內容除了進程號外,其它全部被新程序的內容替換了。另外,這裏的可執行文件既可以是二進制文件,也可以是Linux下任何可執行腳本文件。
- wait
- wait()會暫時停止現在進程的執行,直到有信號來到或子進程結束。假如在調用wait()時子進程已結束,則wait()會立即返回子進程結束狀態值。
- wait()會暫時停止現在進程的執行,直到有信號來到或子進程結束。假如在調用wait()時子進程已結束,則wait()會立即返回子進程結束狀態值。
偽代碼
while(1) { 輸出用戶信息 讀取用戶輸入命令存入數組和文件 調用fork()函數,若返回值不為0,則調用wait() 若返回值為0,調用exec() }
產品代碼
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pwd.h> #include <sys/wait.h> #define N 100 #define order_length 128 #define order_num 64 #define empty 0 #define chars 1 void main() { while(1) { struct passwd *my_info; char path[N]; my_info = getpwuid(getuid()); getcwd(path, sizeof(path)); printf("[%s@%s]$ ", my_info->pw_name, path);//輸出用戶及路徑 char str[N]; char a[N]; char *argv[N]={NULL}; char *envp[]={0,NULL}; int i,j = 0, flag=1; fgets(str,N,stdin); //讀取輸入的命令 str[N - 1] = ‘\0‘; if(feof(stdin)) { printf("error"); exit(0); } for(i=0;str[i]!=‘\0‘&&i<N&&j<N;i++) { if(str[i] == ‘ ‘ || str[i] == ‘\n‘) { flag=1; str[i] = ‘\0‘; } else if(flag==1) { argv[j++] = &str[i]; flag=0; } } if(fork() != 0) wait(NULL); //調用fork() else { execvp(argv[0], argv); perror("execlp error"); exit(0); } } }
測試結果
測試了ls
,ls -l``tree``clear
指令,測試截圖如下:
尚有一部分命令無法實現,例如“cd”等等……
20165322 第七周 mybash 的實現