minishell的实现

所谓程序替换就是替换程序所运行的代码,将另一段程序加载到内存,通过页表改变原来的映射关系,重新建立到新程序内存的地址,相当于替换了进程所运行的程序以及所要处理的数据

exec函数族

迷你shell实现

 

 

  1 #include<stdio.h>
  2 #include<errno.h>
  3 #include<unistd.h>
  4 #include<fcntl.h>
  5 #include<stdlib.h>
  6 //在minishell中添加重定向
  7 
  8 int main(){
  9     while(1){
 10     char str[100]={0};
 11     printf("yang@localhost:");
 12     fflush(stdout);
 13     //我们接受字符串通常有两种方式 gets() 和 scanf()
 14     //gets()
 15     //    1.从标准输入中读取字符串,直到遇见第一个'\n'才读取完成
 16     //    2.并且‘\n’并没有在缓冲区当中,会被系统自动遗弃
 17     //    3.正是因为它的读取如果条件不满足则一直读取,很容易发生读取越界,所以很不安全
 18     //scanf()
 19     //    1.从标准输入中读取字符串,当遇见空白字符时读取完成,并且‘\n’会被遗留在缓冲区中
 20     //    2.正是因为如此,scanf也时不安全的
 21     //    3.解决办法:(正则表达式)
 22     //           1.scanf("%[^\n]",str) --- > %[]表示输入字符集,[^\n]表示读取除了‘\n’意外所有
 23     //             的字符。及空白字符同样接受
 24     //           2.scanf("%[^\n]%*c",str)---->因为除了‘\n’其他都已经被写入数组中,%*c 表示读
 25     //             取缓冲区第一个字符,及‘\n’
 26     //    4,如果scanf()中有两个参数,均得到正确结果返回2
 27     //      如果scanf()中有一个参数,均得到正确结果按返回1
 28     //      如果输入错误,返回 EOF
 29     if(scanf("%[^\n]%*c",str)!=1){
 30         //从标准输入中读取一个字符
 31         getchar();
 32         continue;
 33     }
 34     char* ptr=str;
 35     int redirect_flag=0;
 36     while(*ptr!=0){
 37         if(*ptr=='>'){
 38             redirect_flag=1;
 39             *ptr=0;
 40             ptr++;
 41             if(*ptr=='>'){
 42                 redirect_flag=2;
 43                 *ptr=0;
 44                 ptr++;
 45             }
 46         }
 47     ptr++;
 48     }
 49     int index=0;
 50     char* ptr1=str;
 51     char* buf[100]={0};
 52     while(*ptr1!=0){
 53         //因为不能记录空白字符,所以需要用的isspace()函数来判断
 54         if(!isspace(*ptr1)){
 55             buf[index++]=ptr1;
 56             while(*ptr1!=0&&!isspace(*ptr1)){
 57                 ptr1++;
 58             }
 59             *ptr1='\0';
 60             buf[index]=NULL;
 61         }
 62         ptr1++;
 63     }
 64     //创建子进程
 65     //创建子进程的原因是,在程序被替换后执行完时候会被返回。所以我们可以将程序替换
 66     //放到子进程中,即便子进程退出之后,那么父进程可以继续进行进行循环操作
 67     if(strcmp(buf[0],"cd")==0){
 68         //改变工作路径
 69         chdir(buf[1]);
 70         continue;
 71     }
 72     pid_t pid = fork();
 73     if(pid<0){
 74         perror("fork failure");
 75         return -1;
 76     }else if(pid==0){
 77         int fd=1;
 78         if(redirect_flag==1){
 79             fd=open("test.txt",O_WRONLY | O_CREAT | O_TRUNC);
 80             if(fd<0){
 81                 exit(-1);
 82             }
 83         }else if(redirect_flag==2){
 84             fd=open("text.txt",O_WRONLY | O_CREAT | O_APPEND);
 85             if(fd<0){
 86                 exit(-1);
 87             }
 88         }
 89         printf("%d\n",redirect_flag);
 90         dup2(fd,1);
 91         if(execvp(buf[0],buf)<0){
 92         //如果程序走到这一步表明已经替换失败
 93         exit(0);
 94         }
 95     }else{
 96         wait(NULL);
 97     }
 98   }
 99 return 0;
100 }
101 
102 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值