自主shell原理:首先将读入的字符串分割,然后用fork创建一个子进程,在子进程中调用execvp函数来执行从读入的命令,execvp用新的程序文件替换了子进程原先的执行文件,而父进程等待子进程终止通过调用wait来实现。输入输出重定向由dup函数完成
dup函数请看【转载】:http://blog.sina.com.cn/s/blog_8a41719c0100vwx7.html
#include <unistd.h>
#include <sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<ctype.h>
#define MAX 1024
#define NUM 1024
char* myargv[NUM];
void do_parse(char *cmd)//解析命令行
{
int i = 0;
myargv[i++] = strtok(cmd," ");
char *ret = NULL;
while(ret = strtok(NULL," ")){
myargv[i++] = ret;
}
myargv[i] = NULL;
}
void do_execute()
{
pid_t id =fork();
if(id == 0)
{
int i = 0;
int flag = 0;
//判断命令是否含有输入输出重定向
for(;myargv[i] != NULL;i++)
{
//输出重定向
if(strcmp(myargv[i],">") == 0){
flag = 1;
break;
}
//输入重定向
if(strcmp(myargv[i],"<") == 0){
flag = 2;
break;
}
}
//处理输出重定向
if(flag == 1)
{
myargv[i] = NULL;
int oldfd = open(myargv[i+ 1],O_WRONLY|O_CREAT,0777);
if(oldfd < 0){
perror("open");
exit(1);
}
close(1);
int newfd = dup(oldfd);
}
//输入重定向
if(flag == 2)
{
myargv[i] = NULL;
int oldfd = open(myargv[i+ 1],O_RDONLY,0644);
if(oldfd < 0){
perror("open");
exit(1);
}
close(0);
int newfd = dup(oldfd);
}
execvp(myargv[0],myargv);
exit(1);
}
if(id > 0)
{
waitpid(id,NULL,0);
}
}
int main()
{
char cmd[MAX];
while(1){
printf("[嘻嘻桃子@localhost myshell]# ");
fflush(stdout);
ssize_t s = read(0,cmd,sizeof(cmd)-1);
if(s > 0){
cmd[s-1]=0;
}
do_parse(cmd);//解析命令行
do_execute();//执行命令
}
return 0;
}