什么是shell?

Linux系统的shell作为操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。

shell如何运行程序?

shell用fork建⽴新进程,⽤execv函数簇在新进程中运⾏⽤户指 定的程序,最后shell⽤wait命令等待新进程结束。wait系统调 ⽤同时从内核取得退出状态或者信号序号以告知⼦进程是如何结束的。

编写思路:

①使用while(1)循环实现shell的重复使用
②实现一个接口(函数),功能是将输入的字符串以空格为分界分成多个可执行的字符串,再分别将分隔后的字符串的地址存储在字符指针数组内
eg:
字符串:ls -l
指针数组:char buf[8]//一般一次输入指令的长度不会超过8个
分隔后的存储:buf[0]="ls";buf[1]="-l";buf[3]=NULL;
//这里为什么要加一个buf[3]=NULL;,在下面的“execvp函数的介绍”中会有解释。
③实现一个接口(函数),功能是将已保存“指令字符串的指针”数组挨个读取,使用execvp进行替换实现“指令字符串”对应的指令功能,具体看下面“execvp函数的介绍”。
————————————————
原文链接:https://blog.csdn.net/w_y_x_y/article/details/80013586

execvp函数的介绍:

进程替换空间:将当前进程的用户空间代码和数据完全替换成新程序,但是进程ID并不会变
int execvp(const char* file,char* const argv[]);
//形参分别为(可执行程序名,main函数参数列表)
//第一个参数:可执行程序所在的绝对位置
//第二个参数:可执行程序运行时所需的参数,这里是一个可变参数,每个参数之间用逗号分割
//参数结束时,最后一个参数是:NULL

1_模拟shell(非书本上实验要求):

1、cd /

2、cd home  进入home目录下

3、mkdir testshell  创建一个testshell文件

cd testshell     进入文件夹

4、vim myshell.c

#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#include<ctype.h>
#include<sys/wait.h>void do_execvp(int argc,char* argv[])
{if(fork() == 0)//子进程会进入if,在子进程中fork()返回零,在父进程中返回新创建子进程的进程id{execvp(argv[0],argv);//execvp会将正在运行的进程的内存替换成要执行的进程的内存perror("execvp");//如果走到这步,说明execvp执行失败,因为如果执行成功,这句代码所在的内存已经被替换了,这句代码早就不在了exit(0);//则perror报错并退出程序}wait(NULL);//加一个阻塞,等待子进程结束父进程再运行,防止父进程和子进程并发运行
}void do_parse(char* buf)
{char* argv[8]={};int argc=0;int i=0;int status=0;for(i=0;buf[i]!=0;i++){if(status == 0 && !isspace(buf[i])) { argv[argc++]=buf+i;status=1;}else if(isspace(buf[i]))//判断字符c是否为空白符,当c为空白符时,返回非零值,否则返回零{status=0;buf[i]=0;}}argv[argc]=NULL;do_execvp(argc,argv);
}int main()
{char buf[1024];while(1){printf("my shell>>");memset(buf,0,sizeof(buf));while(scanf("%[^\n]%*c",buf) == 0)//读取失败返回零{while(getchar()!='\n');printf("my shell>>");}//内置命令:不可以使用execvp执行//eg:exitif(strncmp(buf,"exit",4) == 0 )//若输入为exit则返回零,执行退出命令{exit(0);}do_parse(buf);}
}

5、vim Makefile

myshell:myshell.cgcc -o myshell myshell.c
.PHONY:clean
clean:rm -f myshell

注意缩进!!!

6、make  编译

7、./myshell   执行文件

2_实现模拟shell(按照书上实验要求)

编写三个不同的程序cmd1.c、cmd2.c及cmd3.c,每个程序的功能自定,分别编译成可执行文件cmd1、cmd2、cmd3.然后再编写一个程序,模拟shell程序的功能:能根据用户输入的字符串(表示相应的命令名),为相应的命令创建子进程并让他去执行相应的程序,而父进程则等待子进程结束,然后再接收下一条命令。如果接收到的命令为exit,则父进程结束,退出模拟shell;如果接收到的命令是无效命令,则显示“Command not found”,继续等待输入下一条命令。

1、同上新建一个文件夹,进入文件夹目录下

2、编写test1.c

#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void childprocess(int num,char * const argv[],char ** environ){pid_t pid=fork();if(pid<0){printf("Create child process failed \n");}else if(pid==0){switch(num){case 1:execve("cmd1",argv,environ);case 2:execve("cmd2",argv,environ);case 3:execve("cmd3",argv,environ);default:printf("process will never go here");}}
}
int main(int argc,char * const argv[], char **environ){char a[10];while(1){scanf("%s",&a);if (strcmp(a,"exit")==0) break;else if (strcmp(a,"cmd1")==0){childprocess(1,argv,environ);}else if (strcmp(a,"cmd2")==0){childprocess(2,argv,environ);}else if (strcmp(a,"cmd3")==0){childprocess(3,argv,environ);}else printf("Command not found\n");}
}

3、编写cmd1、cmd2、cmd3

#include<stdio.h>
int main(){printf("I'm cmd1\n");
}
#include<stdio.h>
int main(){printf("I'm cmd2\n");
}
#include<stdio.h>
int main(){printf("I'm cmd3\n");
}

4、编译四个文件

5、执行文件 ./test1

杭电操作系统实验三--- 实现模拟shell(arm架构华为云)相关推荐

  1. 杭电操作系统实验一----Linux内核编译及添加系统调用(完整实验报告)

    一 题目介绍 Linux是开源操作系统.在系统中根据需要添加新的系统调用是修改内核的一种常用手段,通过本次实验,我们可以理解Linux系统处理系统调用的流程以及增加系统调用的方法.Linux系统提供了 ...

  2. 杭电操作系统实验二---linux内核模块编译(完整实验报告)

    一 题目介绍 题目内容: (1)当模块被载入内核时会向系统日志文件中写入"hello,world":当被卸载时,会向系统写入"goodbye". (2)设计一个 ...

  3. 杭电操作系统实验一 --- Linux内核编译及添加系统调用(arm架构华为云)

    实验要求  掌握Linux 内核的编译与安装 掌握Linux 系统调用基本概念 设计和添加linux系统调用 (1)修改或返回指定进程的优先级(nice值和prio值)(详见教材P328)提示:可能参 ...

  4. 杭电操作系统实验二 --- Linux 内核模块编程(arm架构华为云)

    一.题目介绍 掌握Linux 内核模块的基本概念 ·阅读教材7.3.2节Linux内核模块简介 ,网上查找资料,了解Linux内核模块的基本概念. ·阅读教材7.3.3内核模块编程基础 ,网上查找资料 ...

  5. linux中关于ssh实验,操作系统实验三linux的telnetftpssh的相关配置及验证

    操作系统实验三linux的telnetftpssh的相关配置及验证 -1-昆明理工大学信息工程与自动化学院学生实验报告( 2010 -2011 学年第 二 学期 )课程名称:操作系统 开课实验室:信自 ...

  6. 操作系统实验三、进程通信

    文章目录 操作系统实验三.进程通信 一.实验目的 二.实验内容 三.设计原理(或方案)及相关算法 四.结果分析 五.源代码 操作系统实验三.进程通信 一.实验目的 ​ 1.了解和熟悉Linux支持的消 ...

  7. arm汇编和c语言混合编程实验报告,实验三C语言和ARM汇编混合编程指导书.doc

    实验三C语言和ARM汇编混合编程指导书 实验三 1. 实验目的 掌握C语言和ARM汇编混合编程方法. 2. 实验设备 硬件:PC 机 一台 软件:Windows98/XP/2000 系统,ADS 1. ...

  8. 超详细!操作系统实验三 系统调用(哈工大李治军)

    实验3 系统调用 提醒 这次实验涉及的宏过于复杂,加上本人能力有限,我也没有花大量时间去研究每一段代码,只是理解到每一段代码做了什么这一程度. 实验目的 此次实验的基本内容是:在 Linux 0.11 ...

  9. 操作系统 实验三 进程调度模拟程序

                                                          实验三 进程调度模拟程序                                   ...

最新文章

  1. 使用Tesseract-OCR训练文字识别记录
  2. 11岁美国男孩用玩具熊“黑”了国际网络安全大会
  3. 工具:分享IntelliJ IDEA 5条调试技巧,太实用了!
  4. P2324 [SCOI2005]骑士精神(迭代加深搜索,dfs)
  5. win7·64bit+VS2013+opencv的简单配置
  6. Java锁的升降级及synchoronized优化
  7. Javascript常见设计模式解析
  8. 计算机网络第七版课后答案(谢希仁版)
  9. android 极光推送1011,极光推送 · OpenKit使用手册 · 看云
  10. 深度学习笔记 摘抄笔记
  11. Postgresql数据库登录的一些问题
  12. Sub Matrix Sum 含负数的最短区间+ 矩阵一维化
  13. 废弃军舰回收站、废铁回炉重造
  14. 无线路由器常用的五种工作模式详细介绍
  15. Linux 修改系统时间的两种方式
  16. SQLyog到期了处理
  17. 计算机的发展史英语作文,选择一种计算机英语作文:求一篇关于计算机发展史的英语作文...
  18. Java面试之语言基础
  19. 【JZOJ 省选模拟】我的朋友们
  20. 【解决】小米MIUI刷机安装完Xposed重启后激活失效

热门文章

  1. SpringMVC学习----请求与响应
  2. 2019软件测试学习教程(学习路线+课程大纲+视频教程+学习工具)
  3. lvgl显示中文和自定义图标
  4. mt,sgd,gd含义
  5. ArcGIS Engine10.0轻松入门级教程(1)——必备基础知识
  6. 高端大气通用企业介绍PPT模板-优页文档
  7. 计算机中丢失cg,【计算机中丢失dll文件】计算机丢失dll文件_计算机中丢失cg dll-win7之家...
  8. RTKLIB学习总结(五)后处理函数调用流程、postpos、execses_b、execses_r、execses、procpos、rtkpos
  9. 计算总成绩和平均成绩
  10. python语法元素测试_基于python全局设置id 自动化测试元素定位过程解析