我们打开一个终端的时候,我们可以在上面输入各种命令,从而与终端实现互动。
可以发现,每当一个指令的执行结束后,终端会等待我们的下一条指令的输入。
这就类似于我们写了一个死循环,一直在等待着命令的输入。当有一条指令输入时,创建子进程并将子进程替换为命令,执行子进程并且父进程等待子进程的执行结束,从而实现交互。执行完后继续等待下一条指令到达。
要实现自主shell,我们主要在循环里要完成以下几项:
- 读入数据
- 解析命令
- 创建子进程执行命令
- 父进程等待子进程结束
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<unistd.h>
#include<string.h>
#include<ctype.h>
#define MAX_NUM 1024
int main(void)
{
int argv = 0;
char* argc[8];
while(1)
{
printf("my shell > ");
char buf[MAX_NUM + 1] = {0};
if(fgets(buf,MAX_NUM,stdin)==NULL)
break;
buf[strlen(buf)-1] = '\0';
printf("[%s]\n",buf);
int i = 0;
int flag = 0;
argv = 0;
for(;buf[i]!='\0';i++)
{
if(!isspace(buf[i])&&flag==0)
{
flag = 1;
argc[argv++] = buf+i;
}
else if(isspace(buf[i]))
{
flag = 0;
buf[i] = '\0';
}
printf("[%c] %d\n", buf[i], flag);
}
argc[argv] = NULL;
for(i = 0; i<argv; i++)
printf("argv[%d] = %s\n", i, argc[i]);
if(fork()==0)
{
execvp(argc[0],argc);
exit(1);
}
else
wait(NULL);
}
printf("886\n");
}
执行结果:
代码里添加了解析命令时的输出,使用时注释掉即可。
但这个自主shell目前只能解析简单的指令,不能解析加上管道后的指令。
暂时还没有实现管道解析和输出重定向。