原理:读取指令,然后复制进程,再将要执行的命令/操作替换
fork +替换
1 #include<stdio.h>
2 #include<sys/wait.h>
3 #include<stdlib.h>
4 #include<unistd.h>
5 #include<assert.h>
6 #include<string.h>
7 #include<pwd.h>
8 #include<errno.h>
9 void printf_info()//打印提示信息
10 {
11 int id =getuid();//获得用户id
12 char *s="$";
13 if(id==0)//说明是管理员用户
14 {
15 s="#";
16 }
17 struct passwd * ptr =getpwuid(id);//通过id获取用户详细信息
18 if(ptr == NULL)
19 {
20 printf("$");
21 fflush(stdout);
22 return;
23 }
24 char hostname[64] = {0};
25 if(gethostname(hostname,64)==-1)//获取主机信息
26 {
27 printf("$");
28 fflush(stdout);
29 return;
30 }
31 char pwd_buff[128] = {0};
32 if(getcwd(pwd_buff,128) == NULL)
33 {
34 printf("$");
35 fflush(stdout);
36 return;
37 }
38 printf("%s@%s %s: %s",ptr->pw_name,hostname,pwd_buff,s);
39 fflush(stdout);
40 }
41 char *get_cmd(char buff[],char*myargv[])
42 {
43 if(buff==NULL||myargv==NULL)
44 {
45 return NULL;
46 }
47
48 char *s =strtok(buff," ");//返回值为字符串地址,分割函数。
49 int i=0;
50 while(s !=NULL)
51 {
52 myargv[i++]=s;
53 s=strtok(NULL," ");
54 }
55 return myargv[0];
56 }
57 int main()
58 {
59 while(1)
60 {
61 char buff[128]={0};//键盘输入的参数和命令
62 printf_info();
63 fgets(buff,128,stdin);//"ls\n"
64 buff[strlen(buff)-1]=0;//去掉最后的\n,因为要进行比对。
65
66 //ls,ps,ps -f,c
67 char*myargv[10]={0};
68 char *cmd=get_cmd(buff,myargv);
69 if(cmd==NULL)
70 {
71 continue;
72 }
73 else if(strcmp(cmd,"exit")==0)
74 {
75 break;//exit(0)也可以
76 }
77 else if(strcmp(cmd,"cd")==0)
78 {
79 if(myargv[1] == NULL)
80 {
81 continue;
82 }
83 if(chdir(myargv[1]) == -1)
84 {
85 perror("cd error");
86 continue;
87 }
88
89 }
90 else
91 {
92 //fork +exec
93 pid_t pid=fork();
94 if(pid==-1)
95 {
96 printf("fork error\n");
97 continue;
98 }
99 if(pid==0)
100 {
101 execvp(cmd,myargv);
102 printf("execvp err\n");
103 exit(0);
104 }
105 wait(NULL);
106 }
107 }
108 exit(0);
109 }