1 /*寫一個屬於自己的微型myshell
2 * 功能:myshell>ls
3 * 能夠執行基礎Linux 命令
4 *
5 */
6 #include<stdio.h>
7 #include<unistd.h>
8 #include<errno.h>
9 #include<string.h>
10 #include<stdlib.h>
11 //1、獲取終端輸入
12 //2、解析輸入(按空格解析到一個一個的命令參數)
13 //3、創建一個子進程
14 // 在子進程中進行程序替換,讓子進程運行命令
15 //4、等待子進程運行完畢,收屍,獲取狀態退出碼
16 int argc;
17 char *argv[32];
18 int param_parse(char *buff){
19 if(buff==NULL)
20 return -1;
21 char *ptr=buff;
22 char *tmp=ptr;
23 argc=0;
24 while((*ptr)!='\0')
25 {
26 //當遇到空格,並且下一個位置不是空格的時候將空格位置置爲'\0'
27 //不過我們將使用argv[argc]來保存這個字符串的位置
28 if(*ptr==' '&&*(ptr+1)!=' ')
29 {
30 *ptr='\0';
31 argv[argc]=tmp;
32 tmp=ptr+1;
33 argc++;
34 }
35 ptr++;
36 }
37 argv[argc++]=tmp;
38 argv[argc]=NULL;
39 }
40
41 int exec_cmd()
42 {
43 int pid=0;
44
45 pid=fork();
46 if(pid<0)
47 {
48 return -1;
49 }else if(pid==0)
50 {
51 execvp(argv[0],argv);
52 exit(0);
53 }
54 //父進程在這裏必須等待子進程退出,來看看子進程爲什麼會退出了
55 //是不是出現了什麼錯誤,通過獲取狀態碼,並且轉換以下退出碼所對應的錯誤信息進行打印
56 int statu;
57 wait(&statu);
58 //判斷子進程是否是代碼運行完畢退出
59 if(WIFEXITED(statu)){
60 //獲取子進程錯誤退出碼,並將轉換打印出文本信息
61 printf("%s\n",strerror(WEXITSTATUS(statu)));
62 }
63 }
64
65 int main()
66 {
67 while(1){
68 printf("myshell>");
69 char buff[1024]={0};
70 //%[^\n] 獲取數據直到遇到\n爲止
71 //%*c 清空緩存區,數據不要了。
72 scanf("%[^\n]%*c",buff);
73 printf("%s\n",buff);
74 param_parse(buff);
75 exec_cmd();
76 }
77
78 return 0;
79
80
來看看運行結果
之前在[long@localhost]進程下執行命令,當實現了自己的shell後,在myshell進程下執行命令,此時Linux默認的進程將成爲bash後臺子程序
./MYSHELL 的父進程ppid爲2543,此時2543對應的進程是bash,所以之前的shell被轉化爲後臺進程,MYSHELL成爲了當前運行的進程。
當前運行的程序爲前臺進程,前臺進程只能有一個,而後臺進程可以有多個,當結束了前臺進程,後臺進程會有一個進程來作爲前臺進程。