对之前编写的自主shell进行修改,使其支持输入/输出/追加重定向

我们之前已经写过相关的代码的问题了,今天我们就对随后的代码进行修改,相关的概念性的问题,在这里我就不再进行多余的赘述了。
我们知道对于Linux来说,shell就是一个命令行解释器,当我们输入相关的命令,会去执行相关的操作。
比如当我们在输入ls -a -l命令,shell就会打印出当前目录的内容,这是如何实现的呢,shell自己就是一个进程,当我们输入类似于ls的命令,它会通过fork,exec去创建一个新的子进程去执行相关操作,因此我们可以利用这个来实现一个简单的shell,当然这个shell足够的简单,并不像Linux内置的shell功能那么强大,支持各种操作,报错等等。
我们先来再聊聊如何去实现一个shell?
1、首先是提示符,rong@host以及当前路径,我们可以使用调用系统api直接打印,这里为了方便,我直接用printf函数打印。
2、解析命令,对于ls -a -l这种操作,我们只需要存入到指针数组中,char* shell_argv[32],ls存到shell_argv[0]当中,-a存到shell_argv[1],-l存到shell_argv[2]……………最后设置为一个NULL
3、利用exev进行调用新的程序。
代码如下:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <string.h>
#include <ctype.h>//isspace函数的头文件
#include <fcntl.h>


int main(){
    for(;;)
    {
    printf("myshell@host:");
    fflush(stdout);//
    //解析输入到shell上的字符串 ls -a -l
    char buffer[1024];
    int read_size=read(1,buffer,sizeof(buffer));
        if(read_size>0){
            buffer[read_size-1]=0;
        }
        char *shell_argv[32]={NULL};
        int shell_index=0;
        char *start=buffer;
        while(*start!='\0'){
            while(*start!='\0'&& isspace(*start)){
            *start='\0';
            start++;
            }
            shell_argv[shell_index++]=start;
            while(*start!='\0' && !isspace(*start)){//
            start++;
            }
        }
        //创建子进程的exec
        pid_t pid=vfork();
        if(pid<0){
            printf("vfork failure\n");
            exit(1);
        }
        else if(pid==0){
            //考虑重定向
            //从字符串数组中找重定向标志
          int i=0;
          int flag=0;
          for(;shell_argv[i]!=NULL;++i){
              if(strcmp(">",shell_argv[i])==0){
              flag=1;
              break;
              }
          }
          int copyfd;
          shell_argv[i]=NULL;
          if(flag)
          {
              if(shell_argv[i+1]==NULL){
              printf("command error\n");
              exit(1);
              }
              close(1);
           int fd=open(shell_argv[i+1],O_WRONLY | O_CREAT,0777);
           copyfd=dup2(1,fd);//把标准输出重新定向到一个文件中
          }
          execvp(shell_argv[0],shell_argv);
          if(flag){
              close(1);
              dup2(copyfd,1);
          }
          exit(1);
        }
        else //father process
                 {
             int status=0;
             int ret=waitpid(pid,&status,0);
             if(ret==pid){
             if(WIFEXITED(status)){
             }
             else if(WIFSIGNALED(status)){
                 printf("signal is %d\n",WTERMSIG(status));
             }
             }
                  }
          }
    return 0;
}

代码执行的结果:

这里写图片描述
但是这个shell暂时也只能实现这些小的命令,对于管道暂时换是不能够进行实现的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值