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

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

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

      

      代码及注释如下:

 //minishell:
//命令行解释器:
//从标准输入读取数据(scanf) ls -l -a
//ls----运行ls命令----ls命令是一个外部程序
//创建一个进程,让这个进程运行ls程序(程序替换)
//读取输入->>命令解析->>创建子进程->>程序替换->>(父进程)进程等待
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<ctype.h>
#include<errno.h>
#include<string.h>
#include<fcntl.h>
#include<sys/wait.h> void Minishell()
{
//循环执行
while(){ //启动格式
printf("minishell:");
fflush(stdout);
char str[]={}; //1.读取输入 ls -a
//需要解决的问题: 空格不截断输入
//scanf返回值:成功:赋值数量,失败:EOF
// %[^\n]---^代表非 []代表字符集,接收所有在\n之前的任意字符
// %*c---*表示不读入(直接取出缓冲区的下一个字符),%*c的作用是为了丢掉\n
if(scanf("%[^\n]%*c",str)!=)
{
getchar(); //接收失败,吸收返回的EOF
}
// printf("cmd:[%s]\n",str); //2.解析命令
//需要解决的问题:命令分割,存储位置
//空格分割命令,模拟命令行参数存储命令
char* p = str;
char* argv[] = {NULL};
int argc = ;
while(*p!='\0')
{
if(*p!=)
{
//存入一个命令
argv[argc]=p;
argc++;
//走到空格
while(*p != && *p!='\0')
{
p++;
}
continue;
}
//遇到空格,分割,加结束标志
else
{
*p='\0';
p++;
}
}
//查看解析
/*int i=0;
for(i;i<argc;i++)
{
printf("argv[%d]--%s\n",i,argv[i]);
}
*/ //3.创建子进程
int pid=fork();
if(pid<)
{
perror("pid error");
exit(-);
}
//4.程序替换
else if(pid==)
{
//功能 : 重定向 -- 使用dup2改变数据流向
int i;
for(i=;i<argc;i++)
{
//> 将原本要写入到终端显示的数据,写入到指定的文件中,并清空文件原有内容
if(strcmp(argv[i],">")==)
{
close();
//打开该文件
int fd = open(argv[argc-],O_CREAT | O_TRUNC | O_RDWR,);
if(fd<)
{
perror("open error\n");
return;
} dup2(fd,);
//直接写入数据
int len;
for(len=;len<i;++len)
{
printf("%s ",argv[len]);
}
printf("\n"); close(fd);
return;
}
//>> 将原本要写入到终端显示的数据,追加写入到指定的文件中
if(strcmp(argv[i],">>")==)
{
close();
//打开文件
int fd = open(argv[argc-],O_CREAT | O_APPEND | O_RDWR,);
if(fd<)
{
perror("open error\n");
return;
}
dup2(fd,);
//直接写入数据
int len;
for(len=;len<i;len++)
{
printf("%s ",argv[len]);
}
printf("\n");
close(fd);
return;
}
}
//非重定向直接程序替换
execvp(argv[],argv);
exit(-);
}
//5.父进程等待子进程退出
waitpid(pid,NULL,); }
} int main()
{
Minishell();
return ;
}

       运行结果展示 :

          

      

      

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

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

    写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾 ...

  2. 只有20行Javascript代码!手把手教你写一个页面模板引擎

    http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...

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

    嗯..再差1篇就可以获得持之以恒徽章了,今天带大家画一个比较简单的view. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/504771 ...

  4. 手把手用Monkey写一个压测脚本

    版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 允许有条件转载,转载请附带底部二维码. 一.为什么需要一个测试脚本? 昨天讲解了Android Monkey命 ...

  5. 手把手教你写一个java的orm(五)

    生成sql:where 上一篇里我们实现了生成insert的sql,下面要开始实现update,delete,select的sql语句了.但是这些语句有一个比较麻烦的地方是:它们一般后面都会有wher ...

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

    写之前的说明 其实吧. 这个东西已经写好了,地址在:https://github.com/hjx601496320/JdbcPlus 这系列文章算是我写的过程的总结吧.(恩系列,说明我可能会写好久,╮ ...

  7. 手把手教你写一个RPC

    1.1 RPC 是什么 定义:RPC(Remote Procedure Call Protocol)--远程过程调用协议 ,RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数 ...

  8. 让我手把手教你写一个强大、方便使用的 IOC 容器

    一.介绍 1.介绍 最近无聊,也没什么事做,没事做总是要给自己找点事情做吧,毕竟人的生活在与折腾.于是,决定自己手动写一个 IOC 的框架.我们知道在 NetCore 的版本里面已经内置了 IOC 容 ...

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

    时间过得真快,眨眼已经快3年了! 1.我的第一个App 还记得我14年初写的第一个iOS小程序,当时是给别人写的一个单机的相册,也是我开发的第一个完整的app,虽然功能挺少,但是耐不住心中的激动啊,现 ...

随机推荐

  1. 【luoguP5091】【模板】欧拉定理

    题目链接 欧拉定理: 当\(a\),\(m\)互质时,\(a^{\phi(m)}\equiv 1 (mod ~ m)\) 扩展欧拉定理: 当\(B>\phi(m)\)时,\(a^B\equiv ...

  2. 鱼塘钓鱼(fishing)(信息学奥赛一本通 1373)

    [问题描述] 有N个鱼塘排成一排(N<100),每个鱼塘中有一定数量的鱼,例如:N=5时,如下表: 即:在第1个鱼塘中钓鱼第1分钟内可钓到10条鱼,第2分钟内只能钓到8条鱼,……,第5分钟以后再 ...

  3. Eclipse R语言开发环境搭建 StatET插件

    StatET 官网 http://www.walware.de/goto/statet Installation 点击菜单栏 help --> Install New Software 配置R语 ...

  4. <英狼>--团队作业3 王者光耀--终极版

    队员 陶俊宇_031702113 卞永亨_031702229 唐怡_031702109 Github 吉哈---King-Shines 队员输出百分比,数据为估值仅供参考 MVP:队长:陶俊宇 60% ...

  5. python selenium chrome 实现自动化登录

    1.环境安装 selenium的开发文档网址(英语好的可以直接看这个,写的很详细):http://selenium-python.readthedocs.io/ 因为实现的时候使用的是谷歌浏览器,在运 ...

  6. 在本地搭建hyperledger fabric 网络

    参考了官方文档,直接就可以了https://hyperledger-fabric.readthedocs.io/en/latest/build_network.html 很好用 ➜ ~ cd $GOP ...

  7. 某表中字段值存在多个Gid逗号分开 取值拆分每个gid SQL多个逗号隔开的取值

    存在值信息 表值函数实现: --实现split功能 的函数 拆分 逗号分开的多个值 ),)) )) as begin declare @i int set @SourceSql=rtrim(ltrim ...

  8. OpenGL基础汇总

    OpenGL(应用程序接口 即API)——用于访问图形硬件的可编程特性 1. 各种矩阵: 世界矩阵(World Matrix):世界矩阵确定一个统一的世界坐标,用于组织独立的物体形成一个完整的场景; ...

  9. Photoshop如何自定义形状

    Photoshop如何自定义形状,自定义形状定义一次,可以随便使用,而且形状无大小,填充后不会有像素问题,普通人可把常用的自定义成形状,很方便.PS中有一些自定义的形状,自己可以随便使用,但是不是很全 ...

  10. [LeetCode] 128. Longest Consecutive Sequence 求最长连续序列

    Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...