手把手带你写一个minishell

  先解释一下Shell : Shell是一个功能为命令行解释器的应用程序,连接了用户和Linux内核,让我们能高效和安全地使用Linux内核。

       要写一个minishell,我们要先理解它的过程:

       读取输入->>命令解析->>创建子进程->>(子进程)程序替换->>(父进程)进程等待

      

      代码及注释如下:

  1 //minishell:
  2 //命令行解释器:
  3 //从标准输入读取数据(scanf)    ls -l -a
  4 //ls----运行ls命令----ls命令是一个外部程序
  5 //创建一个进程,让这个进程运行ls程序(程序替换)
  6 //读取输入->>命令解析->>创建子进程->>程序替换->>(父进程)进程等待
  7 #include<stdio.h>
  8 #include<stdlib.h>
  9 #include<unistd.h>
 10 #include<ctype.h>
 11 #include<errno.h>
 12 #include<string.h>
 13 #include<fcntl.h>
 14 #include<sys/wait.h>
 15
 16 void Minishell()
 17 {
 18   //循环执行
 19   while(1){
 20
 21     //启动格式
 22     printf("minishell:");
 23     fflush(stdout);
 24     char str[1024]={0};
 25
 26     //1.读取输入 ls -a
 27     //需要解决的问题: 空格不截断输入
 28     //scanf返回值:成功:赋值数量,失败:EOF
 29     //  %[^\n]---^代表非 []代表字符集,接收所有在\n之前的任意字符
 30     //  %*c---*表示不读入(直接取出缓冲区的下一个字符),%*c的作用是为了丢掉\n
 31     if(scanf("%[^\n]%*c",str)!=1)
 32     {
 33       getchar();                  //接收失败,吸收返回的EOF
 34     }
 35     //    printf("cmd:[%s]\n",str);
 36
 37     //2.解析命令
 38     //需要解决的问题:命令分割,存储位置
 39     //空格分割命令,模拟命令行参数存储命令
 40     char* p = str;
 41     char* argv[32] = {NULL};
 42     int argc = 0;
 43     while(*p!=‘\0‘)
 44     {
 45       if(*p!=32)
 46       {
 47         //存入一个命令
 48         argv[argc]=p;
 49         argc++;
 50         //走到空格
 51         while(*p !=32 && *p!=‘\0‘)
 52         {
 53           p++;
 54         }
 55         continue;
 56       }
 57       //遇到空格,分割,加结束标志
 58       else
 59       {
 60         *p=‘\0‘;
 61         p++;
 62       }
 63     }
 64     //查看解析
 65     /*int i=0;
 66       for(i;i<argc;i++)
 67       {
 68       printf("argv[%d]--%s\n",i,argv[i]);
 69       }
 70       */
 71
 72     //3.创建子进程
 73     int pid=fork();
 74     if(pid<0)
 75     {
 76       perror("pid error");
 77       exit(-1);
 78     }
 79     //4.程序替换
 80     else if(pid==0)
 81     {
 82       //功能 : 重定向 -- 使用dup2改变数据流向
 83       int i;
 84       for(i=0;i<argc;i++)
 85       {
 86         //>    将原本要写入到终端显示的数据,写入到指定的文件中,并清空文件原有内容
 87         if(strcmp(argv[i],">")==0)
 88         {
 89           close(1);
 90           //打开该文件
 91           int fd = open(argv[argc-1],O_CREAT | O_TRUNC | O_RDWR,0664);
 92           if(fd<0)
 93           {
 94             perror("open error\n");
 95             return;
 96           }
 97
 98           dup2(fd,1);
 99           //直接写入数据
100           int len;
101           for(len=1;len<i;++len)
102           {
103             printf("%s ",argv[len]);
104           }
105           printf("\n");
106
107           close(fd);
108           return;
109         }
110         //>>    将原本要写入到终端显示的数据,追加写入到指定的文件中
111         if(strcmp(argv[i],">>")==0)
112         {
113           close(1);
114           //打开文件
115           int fd = open(argv[argc-1],O_CREAT | O_APPEND | O_RDWR,0664);
116           if(fd<0)
117           {
118             perror("open error\n");
119             return;
120           }
121           dup2(fd,1);
122           //直接写入数据
123           int len;
124           for(len=1;len<i;len++)
125           {
126             printf("%s ",argv[len]);
127           }
128           printf("\n");
129           close(fd);
130           return;
131         }
132       }
133       //非重定向直接程序替换
134       execvp(argv[0],argv);
135       exit(-1);
136     }
137     //5.父进程等待子进程退出
138     waitpid(pid,NULL,0);
139
140
141   }
142 }
143
144 int main()
145 {
146   Minishell();
147   return 0;
148 }

       运行结果展示 :

          

      

      

原文地址:https://www.cnblogs.com/Duikerdd/p/11695138.html

时间: 2024-10-18 04:08:19

手把手带你写一个minishell的相关文章

手把手带你做一个超炫酷loading成功动画view Android自定义view

写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾告一段落,搞完毕设的开题报告后去学习新的内容. 有人对我说类似的效果网上已经有了呀,直接拿来就可以用,为什么还要写.我个人的观点是:第三方控件多数不能完全满足UI的要求,如果需要修改,那么必须理解他的实现,所以很有必要自己去写一款出来,成为程序的创造者,而不单单是使用者.所以,写一写已经实现的效果,

手把手带你画一个动态错误提示 Android自定义view

嗯..再差1篇就可以获得持之以恒徽章了,今天带大家画一个比较简单的view. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50477108 废话不多说,看效果图: 首先 构造函数 测量... 这里就一笔带过了. public ErrorView(Context context) { this(context, null); } public ErrorView(Context context, AttributeSet attrs

大神手把手教你写一个页面模板引擎,只需20行Javascript代码!

只用20行Javascript代码就写出一个页面模板引擎的大神是AbsurdJS的作者,下面是他分享的全文,转需. 不知道你有木有听说过一个基于Javascript的Web页面预处理器,叫做AbsurdJS.我是它的作者,目前我还在不断地完善它.最初我只是打算写一个CSS的预处理器,不过后来扩展到了CSS和HTML,可以用来把Javascript代码转成CSS和HTML代码.当然,由于可以生成HTML代码,你也可以把它当成一个模板引擎,用于在标记语言中填充数据. 于是我又想着能不能写一些简单的代

手把手带你画一个 时尚仪表盘 Android 自己定义View

拿到美工效果图.咱们程序猿就得画得一模一样. 为了不被老板喷,仅仅能多练啊. 听说你认为前面几篇都so easy,那今天就带你做个相对照较复杂的. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50468674 注意:每一篇博客都是建立在之前博客的基础知识上的,假设你刚接触自己定义view.能够来说说自己定义view简单学习的方式这里看我曾经的文章.记录了我学习自己定义view的过程,并且前几篇博客或多或少犯了一些错误(反复绘制,o

手把手教你写一个RN小程序!

时间过得真快,眨眼已经快3年了! 1.我的第一个App 还记得我14年初写的第一个iOS小程序,当时是给别人写的一个单机的相册,也是我开发的第一个完整的app,虽然功能挺少,但是耐不住心中的激动啊,现在我开始学react native,那么现在对于react native也算是有所了解了,就用网上的接口开发一个小程序,现在带大家来写这个程序!接口是用看知乎的API,简简单单的只有get,可以从这里入门,也算是带大家入门吧,过后我会把源代码放在我的github上,前期项目肯定特别简陋,后面慢慢来优

手把手带你画一个漂亮蜂窝view Android自定义view

上一篇做了一个水波纹view  不知道大家有没有动手试试呢点击打开链接 这个效果做起来好像没什么意义,如果不加监听回调 图片就能直接替代.写这篇博客的目的是锻炼一下思维能力,以更好的面多各种自定义view需求. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/50554058 本文是和代码同步写的.也就是说在写文章的时候才敲的代码.这样会显得文章有些许混乱.但是我想这样记录下来,一个自定义view的真正的制作过程,是一点一点,一步步跟

手把手教你写一个java的orm(二)

创建映射关系 ? 想要实现一个orm的功能,我觉得就是要将class和数据库中的表创建映射关系.把class的名称和表的名称,class属性名称和表的字段名称,属性类型与表的字段类型一一对应起来.可以通过配置文件,注解等等各种方式实现这个映射关系. 需要的依赖 ? 因为编写配置文件总是一件十分繁琐的事情,所以我决定使用注解的方式来实现这个映射.在项目刚开始写的时候我用的是自定义注解的方法.自己规定一套注解,后来觉得这样没有太大的必要,因为已经有jpa里的一套注解.所以直接用就好了.所以添加依赖:

手把手教你写一个java的orm(完)

生成sql:select 上一篇讲了怎样生成一个sql中where的一部分,之后我们要做事情就简单很多了,就只要像最开始一样的生成各种sql语句就好了,之后只要再加上我们需要的条件,一个完整的sql就顺利的做好了. 现在我们开始写生成查询语句的sql.一个查询语句大致上是这样的: SELECT name, id, create_date, age, mark, status FROM user 这里可以看出来,一个基础的查询语句基本上就是一个 SELECT 后面加上需要查询的字段,跟上 FROM

手把手教你写一个用pytorch实现的Lenet5

最近为了实现HR-net在学习pytorch,然后突然发现这个框架简直比tensorflow要方便太多太多啊,我本来其实不太喜欢python,但是这个框架使用的流畅性真的让我非常的喜欢,下面我就开始介绍从0开始编写一个Lenet并用它来训练cifar10. 1.首先需要先找到Lenet的结构图再考虑怎么去实现它,在网上找了一个供参考 2.需要下载好cifar-10的数据集,在pytorch下默认的是下载cifar-10-python版本的,由于官网速度较慢,我直接提供度娘网盘的链接:链接:htt