shell执行过程:
1.读取用户从键盘输入的命令(调用read函数);
2.分析命令,以命令名为文件名,并将其他参数改造为系统调用execvp()参数处理所要求的格式;
3.终端进程(shell)调用fork()或者vfork()建立一个子进程;
4.子进程依据文件名(命令名)到目录中查找有关文件,将他调入内存,并创建新的文本段,并根据写时拷贝的方式创建相应的数据段,堆栈段;
5当子进程完成处理或者出现异常后,通过调用exit()函数向父进程报告;
6.终端进程调用wait()函数等待子进程完成,并对子进程进行回收。
注: 目前不支持 管道 重定向 等功能
#include<stdio.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main()
{
//初始化数组
char buf[1024] = { 0 };
while(1)
{
printf("[myshell]$ ");
fflush(stdout); //刷新
size_t s = read( 0, buf, sizeof( buf )- 1); //从键盘读入字符串
if(s > 0)
{ //读取成功
buf[s - 1] = '\0'; //字符串加\0表示结尾
}
else
{
perror("read"); //读取失败
return 1;
}
char* argv[32];
argv[0] = buf;
char* start = buf;
int i = 1;
while(*start)
{
if(*start == ' ') //如果从空格开始到字符串
{
*start = '\0'; //加上\0作为结束
start ++; //从下一个字符开始
argv[i++] = start;
}
else // 从字符串开始到空格
{
start ++;
}
}
argv[i] = NULL;
pid_t pid;
pid = fork();
if(pid < 0) //创建进程失败
{
perror("fork");
exit(1);
}
if(pid == 0) //子进程
{
execvp(argv[0], argv); //查找符合命令的参数执行该文件,
return 2 ;
}
else if(pid > 0) //父进程
{
int st = 0;
wait(&st); //等待子进程的退出码
}
}
return 0;
}