手把手带你写一个minishell
先解释一下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的更多相关文章
- 手把手带你做一个超炫酷loading成功动画view Android自定义view
写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾 ...
- 只有20行Javascript代码!手把手教你写一个页面模板引擎
http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...
- 手把手带你画一个动态错误提示 Android自定义view
嗯..再差1篇就可以获得持之以恒徽章了,今天带大家画一个比较简单的view. 转载请注明出处:http://blog.csdn.net/wingichoy/article/details/504771 ...
- 手把手用Monkey写一个压测脚本
版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 允许有条件转载,转载请附带底部二维码. 一.为什么需要一个测试脚本? 昨天讲解了Android Monkey命 ...
- 手把手教你写一个java的orm(五)
生成sql:where 上一篇里我们实现了生成insert的sql,下面要开始实现update,delete,select的sql语句了.但是这些语句有一个比较麻烦的地方是:它们一般后面都会有wher ...
- 手把手教你写一个java的orm(一)
写之前的说明 其实吧. 这个东西已经写好了,地址在:https://github.com/hjx601496320/JdbcPlus 这系列文章算是我写的过程的总结吧.(恩系列,说明我可能会写好久,╮ ...
- 手把手教你写一个RPC
1.1 RPC 是什么 定义:RPC(Remote Procedure Call Protocol)--远程过程调用协议 ,RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数 ...
- 让我手把手教你写一个强大、方便使用的 IOC 容器
一.介绍 1.介绍 最近无聊,也没什么事做,没事做总是要给自己找点事情做吧,毕竟人的生活在与折腾.于是,决定自己手动写一个 IOC 的框架.我们知道在 NetCore 的版本里面已经内置了 IOC 容 ...
- 手把手教你写一个RN小程序!
时间过得真快,眨眼已经快3年了! 1.我的第一个App 还记得我14年初写的第一个iOS小程序,当时是给别人写的一个单机的相册,也是我开发的第一个完整的app,虽然功能挺少,但是耐不住心中的激动啊,现 ...
随机推荐
- 关于System.ExecutionEngineException异常
什么是System.ExecutionEngineException 公共语言运行库的执行引擎中出现内部错误时引发的异常.这个类不能继承. 继承 Object Exception SystemExce ...
- cube.js 学习 cube 连接mongodb 试用
cube.js 对于mongodb 的连接是通过mongodb bi connector(mysql 协议)处理的,以下为简单的试用 安装mongo bi connector 这个玩意用docker ...
- Cocos Creator打包发布
若本号内容有做得不到位的地方(比如:涉及版权或其他问题),请及时联系我们进行整改即可,会在第一时间进行处理. 请点赞!因为你们的赞同/鼓励是我写作的最大动力! 欢迎关注达叔小生的简书! 这是一个有质量 ...
- Uncaught SyntaxError: Unexpected token o
浏览器报Uncaught SyntaxError: Unexpected token o 这原因是你ajax获取数据的时候对数据进行错误操作,比如使用了 JSON.parse(data) 对数据进行转 ...
- Eclipse 高亮显示(pydev 编辑 python)
因为是使用pydev编辑的python,所以需要修改(pydev)的属性. Window->Preferences->General->Editors->Text Editor ...
- 【AE软件】视频添加字幕
1.导入视频 2.将视频拖入大屏幕 3.在下面点击右键——新建——文本 4.文字属性设置
- SpringBoot异步及线程池配置
异步方法注解@Async 在SpringBoot中进行异步处理,可以使用异步注解@Async和@EnableAsync. @Async注解表示异步,如:@Async("asyncServic ...
- 安装OpenStack Queens版本的教程推荐
为了加深对OpenStack的理解,需要自己分模块安装一次,之前都是用devstack安装,傻瓜式安装虽然方便,但是也减少了我对OpenStack理解的深度. 本人参考如下文档安装成功过 http:/ ...
- gradle 使用maven repository 的设置
repositories { //Maven中心库(http://repo1.maven.org/maven2) mavenCentral() //本地库,local repository ...
- [转]IntelliJ IDEA 2019 上手
原文地址:https://www.jianshu.com/p/77f81d5fcf02 一.聊一聊Java IDE 作为程序员,经常会看到这么一类的话题:文本编辑器与IDE哪家强.常见的文本编辑器如E ...