在学习了Linux的进程控制之后,学习了fork函数和exec函数族,通过这些个函数可以简单的实现一份shell,就是实现一份命令行解释器,当然是简单版的,实现功能如下能执行普通的命令如ls ,ps ,top等可以实现目录的跳转cd命令能执行命令并加上参数如ls-l能执行打开ma ...
在学习了Linux的进程控制之后,学习了fork函数和exec函数族,通过这些个函数可以简单的实现一份shell,就是实现一份命令行解释器,当然是简单版的,实现功能如下
- 能执行普通的命令如ls ,ps ,top等
- 可以实现目录的跳转cd命令
- 能执行命令并加上参数如ls-l
- 能执行打开man手册
- 能识别管道符
还不能实现正则表达式,要实现这个我当前的代码根本不能用,要重头开始改写。。。
下面贴代码
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <string.h> 4 #include <sys/types.h> 5 #include <sys/wait.h> 6 #include <stdlib.h> 7 #include <pwd.h> 8 #include <sys/utsname.h> 9 #include <libgen.h> 10 11 12 void eatblank(char **buf) 13 { 14 while(**buf==' ') 15 { 16 (*buf)++; 17 } 18 } 19 20 21 void GetHostName(char *hostname,int length) 22 { 23 gethostname(hostname,length); 24 char *p=hostname; 25 while(*p!='\0') 26 { 27 if(*p=='.') 28 { 29 *p='\0'; 30 } 31 p++; 32 } 33 } 34 35 void Pipe(char **my_argv,char *buf); 36 void BuildCommand(char **my_argv,char *buf) 37 { 38 eatblank(&buf); 39 my_argv[0]=buf; 40 int index=1; 41 char *p=buf; 42 while(*p!='\0') 43 { 44 if(*p==' ') 45 { 46 *p='\0'; 47 p++; 48 eatblank(&p) ; 49 if(*p!='|') 50 { 51 my_argv[index++]=p; 52 } 53 continue; 54 } 55 else if(*p=='|') 56 { 57 p++; 58 //p++; 59 my_argv[index]=NULL; 60 Pipe(my_argv,p); 61 } 62 else 63 { 64 p++; 65 } 66 } 67 my_argv[index]=NULL; 68 } 69 70 71 72 void Pipe(char ** my_argv,char *buf) 73 { 74 int fd[2]; 75 pipe(fd); 76 pid_t id2=fork(); 77 if(id2==0) 78 { 79 close(1); 80 dup(fd[1]); 81 close(fd[1]); 82 close(fd[0]); 83 execvp(my_argv[0],my_argv); 84 } 85 else 86 { 87 waitpid(id2,NULL,0); 88 close(0); 89 dup(fd[0]); 90 close(fd[0]); 91 close(fd[1]); 92 BuildCommand(my_argv,buf); 93 execvp(my_argv[0],my_argv); 94 } 95 //在此处添加exec族函数 96 } 97 98 99 int main()100 {101 while(1)102 {103 char *my_argv[64];104 struct passwd *pwd=getpwuid(getuid());105 char hostname[256]={'\0'};106 char cwd[256]={'\0'};107 getcwd(cwd,256);108 GetHostName(hostname,256);109 printf("[%s@%s %s]#",pwd->pw_name,hostname,basename(cwd));110 fflush(stdout);111 char buf[1024];112 buf[0]='\0';113 114 int count=read(0,buf,sizeof(buf));115 buf[count-1]='\0';116 my_argv[0]=buf; 117 pid_t id=fork();118 if(id==0)119 {120 //child121 122 if(strncmp(buf,"cd",2)==0) 123 {124 exit(1);125 }126 BuildCommand(my_argv,buf);127 execvp(my_argv[0],my_argv);128 printf("if the process has some problem ,I should run here\n");129 exit(0);130 }131 else132 {133 //father134 int status=0;135 wait(&status);136 if(status==256)137 {138 my_argv[0]+=3;139 chdir(my_argv[0]);140 }141 }142 }143 return 0;144 }
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:模拟Linux的shell
关键词:linux
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。