要模拟实现shell,我们首先要搞清楚它是怎么工作的,在Linux操作系统下:
首先,shell先读入命令,然后创建子进程,让子进程完成读入的命令,这就需要用到进程替换,让子进程执行另一段程序;而父进程负责等待子进程的结束,子进程结束后,就可以读取新的命令了。
下面就是具体的实现:
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
char* argv[8];//定义命令行参数列表
int argc = 0; //定义命令行参数个数
void do_phrase(char buf[])
{
assert(buf);
//将buf数组中的内容加到命令行参数列表中
int i = 0;
int status = 0;
for(argc = i = 0; i < 8; ++i)
{
if(buf[i] != ' ' && status == 0)
{
argv[i] = &buf[i];
argc++;
status = 1;
}
else if(buf[i] == ' ')
{
status = 0;
buf[i] = 0; //每个字符串的结束
}
}
argv[argc] = NULL;
}
void do_execute()
{
//先创建一个进程
int pid = fork();
switch(pid)
{
case -1:
perror("fork");
break;
case 0:
//在子进程中进行程序替换,执行另一串命令
execvp(argv[0], argv);
//未进行程序替换成功,走到这一步
perror("execvp");
exit(EXIT_FAILURE);
break;
default:
//在父进程中等待子进程执行结束
{
int st = 0;
int ret = wait(&st);
while(ret != pid);
break;
}
}
}
int main()
{
char buf[1024] = {};
while(1)
{
printf("myshell>");
scanf("%[^\n]%*c", buf); //获取字符
do_phrase(buf); //解析字符
do_execute(); //程序替换
}
return 0;
}