2017-2018-1 20155320 第五周 加分题-mybash的实现
2017-2018-1 20155320 第五周 加分题-mybash的实现
- 使用fork,exec,wait实现mybash
- 写出伪代码,产品代码和测试代码
- 发表知识理解,实现过程和问题解决的博客(包含代码托管链接)
学习函数的使用
使用man命令来查找函数的使用
- fork函数
fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。一个进程调用fork()函数后,系统先给新的进程分配资源.
父进程从fork返回处继续执行,在父进程中,fork返回子进程PID
子进程从fork返回处开始执行,在子进程中,fork返回0
其实对fork函数中子进程与父进程的调用感觉有点绕,然后又学习了一下娄老师提供的几个demo代码,运行结果如下:
n个fork,2^n个after
fork()返回中1代表父进程,0代表子进程
- exec函数
fork函数是用于创建一个子进程,该子进程几乎是父进程的副本,而有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法
- wait函数
常用来阻塞进程,当父进程的所有子进程都还在运行,调用wait将使父进程阻塞。
mybash的实现
- 根据娄老师上课所讲的思路,就是在父进程中用while循环来根据命令调用命令的实现1.命令以字符串的形式输入 2. pid用来区分进程
伪代码
while(1){
输入命令
创建子进程
执行命令
等待命令执行结束
}
产品代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#define len 100
#define MAX 100
typedef int pid_t;
char* make(char *buf)//将字符串传入参数表内
{
char *cp;
cp=malloc(strlen(buf)+1);
if (cp==NULL)
{
fprintf(stderr,"no memory\n");
exit(1);
}
strcpy(cp,buf);
return cp;
}
int change(char *buf,char *arglist[])//对于字符串进行分割
{
int num,j,i,last;
char buffer[len];
num=0;
i=0;
while (num<MAX)
{
if (buf[i]=='\n')
{
arglist[num]=NULL;
return num;
}
if (buf[i]==' ') i++;
last=i;
while (buf[i]!=' ' && buf[i]!='\n') i++;
for (j=last;j<i;j++) buffer[j-last]=buf[j];
buffer[j-last]='\0';
arglist[num++]=make(buffer);
}
}
int main(){
pid_t pid;
char *arglist[MAX];//shell指令参数表
char buf[len];
int x;
while(1){
printf("mybash~:");
fflush(stdout);
fgets(buf,len,stdin);//读入单行指令
x=change(buf,arglist);
/*for(x=0;x<strlen(buf)-1;x++){
*arglist[x]=buf[0];
}*/
pid=fork();//创建一个子进程
if(pid<0) /* 如果出错 */
printf("error ocurred!/n");
if(pid==0){
execvp(arglist[0],arglist);//执行命令
}
waitpid(pid,NULL,0);//等待子进程结束
}
return 0;
}
- 实现结果
实现中出现的问题
- 问题1:第一次运行时,不知道为啥命令运行不了
- 解决1:看了几个同学的博客,说加一个/bin,但我尝试了一下仍然无法运行。出现了如下图所示情况
- 解决2:通过仔细查看之前出现的警告,我发现我犯了个愚蠢的错误,execvp函数中需要指针传参。
解决3:我尝试将buf的值赋给指针数组arglist,结果出现段错误
解决4:通过网上查询,在linux下shell的简单实现,研究了一下别人的代码,给我一些启发,发现重新修改了一下buf和arglist的转换,终于正确了
2017-2018-1 20155320 第五周 加分题-mybash的实现的更多相关文章
- 20155326 第五周加分题--mybash的实现
第五周加分题--mybash的实现 题目要求 1.使用fork,exec,wait实现mybash 2.写出伪代码,产品代码和测试代码 3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接) ...
- 第五周加分题--mybash的实现
第五周加分题--mybash的实现 题目要求 1.使用fork,exec,wait实现mybash 2.写出伪代码,产品代码和测试代码 3.发表知识理解,实现过程和问题解决的博客(包含代码托管链接) ...
- 第五周 加分题-mybash的实现
第五周 加分题-mybash的实现 使用fork,exec,wait实现mybash 产品代码 #include <stdio.h> #include <stdlib.h> # ...
- 20155308 加分题-mybash的实现(第五周)
20155308 加分题-mybash的实现(第五周) 实验要求 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解,实现过程和问题解决的博客(包含代码托管 ...
- 2017-2018-1 20155239 《信息安全系统设计基础》第五周学习总结+mybash的实现
2017-2018-1 20155239 <信息安全系统设计基础>第五周学习总结+mybash的实现 mybash的实现 使用fork,exec,wait实现mybash 写出伪代码,产品 ...
- 程序设计入门—Java语言 第五周编程题 2井字棋(5分)
2 井字棋(5分) 题目内容: 嗯,就是视频里说的那个井字棋.视频里说了它的基本思路,现在,需要你把它全部实现出来啦. 你的程序先要读入一个整数n,范围是[3,100],这表示井字棋棋盘的边长.比如n ...
- 20155339 第七周加分项目 mybash的实现
mybash的实现 要求 使用fork,exec,wait实现mybash 写出伪代码,产品代码和测试代码 发表知识理解,实现过程和问题解决的博客(包含代码托管链接) 学习相关知识 fork函数 查看 ...
- 20155320 2016-2017-2 《Java程序设计》第五周学习总结
20155320 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 错误处理 java中所有错误都会被打包为对象,可以通过try catch 代表错误的对象后做 ...
- 2017面向对象程序设计(Java)第十五周学习总结
上周,老师要求同学们自学应用程序部署,并布置了相关的实验任务.此次实验的目的是掌握Java应用程序的打包操作:了解应用程序存储配置信息的两种方法: 了解Applet小应用程序的开发及应用方法:掌握基于 ...
随机推荐
- maven(19)-生命周期和内置插件
生命周期和依赖一样,是maven中最重要的核心概念.平时在使用maven时并不一定需要知道生命周期,但是只有明白了生命周期,才能真正理解很多重要的命令和插件配置. default生命周期 defaul ...
- 百度开源的分布式 id 生成器
UidGenerator是Java实现的, 基于Snowflake算法的唯一ID生成器.UidGenerator以组件形式工作在应用项目中, 支持自定义workerId位数和初始化策略, 从而适用于d ...
- Oracle特殊恢复原理与实战(DSI系列)
1.深入浅出Oracle(DSI系列Ⅰ) 2.Oracle特殊恢复原理与实战(DSI系列Ⅱ) 3.Oracle SQL Tuning(DSI系列Ⅲ)即将开设 4.Oracle DB Performan ...
- sql建JOB语句
declare job_id pls_integer; begin sys.dbms_job.submit(job => job_id, what => 'proc_AGTAWBSTATI ...
- iOS7中UIView的animateKeyframesWithDuration方法讲解
iOS7中UIView的animateKeyframesWithDuration方法讲解 在iOS7中,给UIView添加了一个方法用来直接使用关键帧动画而不用借助CoreAnimation来实现,那 ...
- Linux 系统的磁盘设备_【all】
磁盘 ->RAID ->分区 ->格式化 ->挂载 基本的框架 a.硬盘的外部以及内部硬件结构,工作原理和读写原理b.RAID的划分(一块盘划分为一块或者多块的小虚拟磁盘,可以 ...
- sql server 使用链接服务器连接Oracle,openquery查询数据
对接问题描述:不知道正式库oracle数据库账户密码,对方愿意在对方的客户端上输入账号和密码,但不告诉我们 解决方案:使用一台sql server作为中间服务器,可以通过转存数据到sql serv ...
- 到底该用img还是background-image?
在前端页面的实现过程中,我们经常会遇到这个情况:有一个盒子,盒子里面需要放一张图片.这个时候,我们既可以通过添加image标签来实现,也可以通过设置背景图的形式实现,哪种更好呢? 一般情况下,可能就是 ...
- tomcat 开启远程debug
修改 tomcat 目录下 /bin/catelina.sh # execution immediately after startup. Default is ...
- mybatis #{}和${}的区别是什么
#{}和${}的区别是什么?正确的答案是:#{}是预编译处理,${}是字符串替换.(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法 ...