通过Linux实现一个mini_shell
进程控制是学习系统的一个重要知识点,涵盖有进程创建,进程终止,进程等待,程序替换这些方面。在学完这些知识后,想通过这个mini_shell将之前学过知识做一个小小的综合。
思路:
- 获取命令行
- 解析命令行
- 建立一个子进程
- 替换子进程
- 父进程等待子进程退出
首先第一步获取命令行,想想之前学过获取数据的方法,有scanf(),fgets();
//scanf返回值,成功则返回正确读的项数
char cmd[1024] = {0};//定义一个数组来接受数据
// scanf本身是遇到空格就需要获取一次,这样的话就无法获取到一个完整的命令,因此%[^\n]表示的是获取数据直到\n为止%*C 将缓冲区中的字符都取出来,但是不要他,直接丢掉,目的是为了将最后的\n从缓冲区中取出来。防止陷入死循环。
if(scanf(“%[^\n]%*c”,cmd)!= 1)
{
getchar();
}
//函数原型: char * fgets ( char * str, int num, FILE * stream );
#define MAX 1024
char cmd[MAX];
fgets(cmd,MAX,stdin);
第二步解析命令行
在C语言中我们曾经学过一个函数strotok()。函数原型:
char * strtok ( char * str, const char * delimiters );
strtok()用来将字符串分割成一个个片段。参数s 指向欲分割的字符串,参数delim 则为分割字符串,当strtok()在参数s 的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s 字符串,往后的调用则将参数s 设置成NULL。每次调用成功则返回下一个分割后的字符串指针。
返回值:返回下一个分割后的字符串指针,如果已无从分割则返回NULL。
i++;
while(1)
{
char* p = strtok(NULL, " ");
if(p == NULL)
{
myargv[i] = NULL;
break;
}
myargv[i] = p;
i++;
创建子进程并且替换程序
pid_t id = fork();
32 if(id < 0)
33 {
34 printf("error");
35 exit(1);
36 }
37 else if(id == 0)
38 {
39
40 execvp(myargv[0],myargv);
41 }else{
42 waitpid(id , NULL ,0);
43 }