先解释一下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. 【数位DP】数字统计

    题目 给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次. 数位DP (1)分情况,逐位讨论. (2)模型:计算在[L,R]中有多少个数满足条件. (3)套路:将 ...

  2. c++ Size capacity Resize reserve shrink_to_fit

  3. 洛谷P4343 [SHOI2015]自动刷题机

    题目 易得该题目中的\(n\)和\(k\)具有单调性,满足二分的性质,因此该题目而已用二分来枚举\(n\),然后对于每个\(n\)模拟出它所对应的\(k\),然后注意注意代码细节,并且当当前\(k\) ...

  4. Spark跑在Yarn上出现错误,原因是jdk的版本问题

    ./bin/spark-shell --master yarn 2019-07-01 12:20:13 WARN NativeCodeLoader:62 - Unable to load native ...

  5. mysql 日期处理

    mysql> select curdate(); +------------+ | curdate() | +------------+ | -- | +------------+ row in ...

  6. 从0开始部署GPU集群-0:基本情况

    配置信息(多台服务器) 1 硬件:CPU和GPU*可选 2 操作系统:centos7 3 驱动:nvidia显卡驱动  *可选 4 容器运行时:docker 和 nvidia container ru ...

  7. 关于资源获取(请把https改为http)

    所有demo以及资源获取,请把https改为http.

  8. Deep High-Resolution Representation Learning for Human Pose Estimation

    Deep High-Resolution Representation Learning for Human Pose Estimation 2019-08-30 22:05:59 Paper: CV ...

  9. python简单的游戏场景代码

    模拟英雄联盟游戏场景的简单场景 最后计算出英雄的战斗力 class Hero: def __init__(self, na, gen, age, fig): self.name = na self.g ...

  10. iptables实现端口映射(本地和远程端口映射)

    说明:需要将外网访问本地IP(192.168.75.5)的80端口转换为访问192.168.75.3的8000端口,这就需要用到iptables的端口映射 实现:1. 需要先开启linux的数据转发功 ...