Linux下模擬實現一個微型shell
阿新 • • 發佈:2018-12-16
首先我們先看一下shell的執行過程:
shell從使用者讀入字串"ls",並建立一個新的程序,在那個程序中執行ls程式並等待那個程序結束。然後shell讀取新的一行輸入,建立一個新的程序,在這個程序中執行程式並等待這個程序結束。
所以我們要寫一個微型shell,需要迴圈以下過程:
- 獲取終端輸入。
- 解析輸入(按空格解析到一個一個的命令引數)。
- 建立一個子程序,在子程序中進行程式替換,讓子程序執行命令。
- 等待子程序執行完畢,收屍,獲取退出狀態碼。
根據這個思路和我們之前學習到的知識,就可以自己實現一個微型shell了。
來看程式碼(使用Linux作業系統實現):
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<errno.h> #include<string.h> int argc; char *argv[32]; int param_parse(char *buff) { // ls -l if (buff == NULL) return -1; char *ptr = buff; char *tmp = ptr; argc = 0; while ((*ptr) != '\0') { //當遇到空格,並且下一個位置不是空格的時候,將空格位置置位為'\0' //然後用argv[argc]來儲存這個字串的位置 if ((*ptr) == ' ' && *(ptr + 1) != ' ') { *ptr = '\0'; argv[argc] = tmp; tmp = ptr + 1; argc++; } ptr++; } argv[argc++] = tmp; argv[argc] = NULL; return 0; } int exec_cmd() { int pid = 0; pid = fork(); if (pid < 0) return -1; else if (pid == 0) { execvp(argv[0], argv); exit(0); } //父程序在這裡必須等待子程序退出,來看看子程序為什麼退出了,是不是出現了什麼錯誤。 //通過獲取狀態碼,並且轉換一下退出碼所對應的錯誤資訊進行列印。 int statu; wait(&statu); //判斷子程序是否程式碼執行完畢退出 if (WIFEXITED(statu)) { //獲取到子程序的退出碼,轉換為文字資訊列印。 printf("%s\n", strerror(WEXITSTATUS(statu))); } return 0; } int main() { while (1) { printf("mashell> "); char buff[1024] = { 0 }; // %[^\n] 獲取資料直到遇到\n為止 // %*c 清空緩衝區,資料都不要了 scanf("%[^\n]%*c", buff); printf("%s\n", buff); param_parse(buff); exec_cmd; } return 0; }
測試結果: