通過獲取子程序建立的一個迷你版的
阿新 • • 發佈:2018-12-03
整個程式執行分為四部分:
-
- 寫一個shell的入口,用於提示要輸入資訊
-
- scanf接收一個輸入資訊
-
- 建立子程序
-
- 程式替換
輸入資訊:
- 程式替換
printf("minishell: "); fflush(stdout); char cmd[1024] = {0}; if (scanf("%[^\n]%*c", cmd) != 1) { getchar(); }
^\n:scanf本身是遇到空格就要獲取一次,這樣的話就無法獲取
到一個完整的命令,因此‘%[^\n]’表示的是獲取資料直到遇到\n為止
%*c:將緩衝區中的字元都取出來,但是不要它,直接丟掉
目的是為了將最後的\n從緩衝區取出來,防止陷入死迴圈
解析獲得的命令:
在char *ptr = cmd; char *argv[32] = {NULL}; int argc = 0; argv[argc++] = ptr; while(*ptr != '\0') { int isspace(int c); //用於判斷一個字元是否是:\t \n \r 空格 //解析一個字串時候這裡就是對空格的判斷 if (isspace(*ptr)) { while(isspace(*ptr) && *ptr != '\0') { *ptr++ = '\0'; } argv[argc++] = ptr; } ptr++; } if (fork() == 0) { execvp(argv[0], argv); }
子程序建立程式替換:
if (fork() == 0) {
execvp(argv[0], argv);
}
wait(NULL);
需要等待的原因:
1. 避免產生殭屍子程序
2. 是為了等待子程序執行完畢,讓程式邏輯更加完善
完整版程式實現如下:
int main() { while(1) { printf("minishell: "); fflush(stdout); char cmd[1024] = {0}; if (scanf("%[^\n]%*c", cmd) != 1) { getchar(); } char *ptr = cmd; char *argv[32] = {NULL}; int argc = 0; argv[argc++] = ptr; while(*ptr != '\0') { if (isspace(*ptr)) { while(isspace(*ptr) && *ptr != '\0') { *ptr++ = '\0'; } argv[argc++] = ptr; } ptr++; } if (fork() == 0) { execvp(argv[0], argv); } wait(NULL); } return 0; }