模拟实现shell,使它支持重定向功能

我们都知道用户是通过操作系统来对我们的硬件或者软件进行操作的,但是我们平时在使用计算机的时候并没有直接与操作系统进行交流。而在linux下我们通常通过终端输入命令,但是你有没有想过为什么我们在终端输入命令,操作系统就能认识呢?这中间存在一个命令行解释器shell,也就是所谓的外壳程序,来对我们输入的命令进行解释,调用相关的系统调用接口,从而实现各种操作。在这里我们就来模拟一个shell。

要模拟shell,我们首先得知道shell的工作原理:在我们打开终端的同时,我们也就将shell这个进程加载到内存中了,而对于我们输入的每一条命令,它也就是一个个可执行程序,也就是我们的shell这个进程通过fork()这个系统调用生成的子进程,shell这个进程本身并不会执行我们的命令功能,而是让它的子进程去执行对应操作,而它自己则是等待子进程返回,来回收子进程的资源。

要模拟实现shell,必然要和shell的功尽量贴切,而对于shell有一项功能需要注意,就是输出重定向。

对于我们的输出重定向,无非就是对于我们的输出在显示器文件上的东西重新定位到我们的文件中,所以这里只要对于文件描述符“1”进行关闭,而之后打开我们的文件即可(文件描述符1------stdout(原本时输出到显示器文件))

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<ctype.h>
int main(){
while(1){
pid_t pid = fork();
if(pid == 0){
printf("[[email protected]]$");
fflush(stdout);
char buf[1024];
ssize_t readnum  = read(0,buf,sizeof(buf)-1);
if(readnum > 0){
buf[readnum-1] = 0;//处理'\0'
}
char* start = buf;
char* argv[32];
memset(argv,0,32);
argv[0] = start;
ssize_t index = 1;
while(*start){
if(isspace(*start)){
*start = '\0';
start++;
if(*start == '>'){
start++;
while(isspace(*start)){
start++;
}
char filename[32];
int idx = 0;
while(!isspace(*start)&&*start!='\0'){
filename[idx] = *start;
idx++;
start++;
}
filename[idx] = '\0';
close(1);
int fd = open((const char*)filename,O_WRONLY|O_CREAT,0644);
}
else
argv[index++] = start;
}
else{
start++;
}


}
argv[index] = NULL;
execvp(argv[0],argv);
exit(1);
}
else{
waitpid(pid,NULL,0);
}
}
return 0;

}

模拟实现shell,使它支持重定向功能