Linux课程设计进程控制
进程控制实验报告

一、实验目的本次实验旨在通过Linux操作系统的实践操作,加深对进程控制概念的理解。
通过学习进程的创建、调度、同步、通信等基本操作,掌握进程控制的基本方法,并了解进程间通信的机制。
二、实验环境1. 硬件环境:Intel(R) Core(TM) i5-3210M CPU2.50GHz,4.00GB内存。
2. 软件环境:64位Linux操作系统。
三、实验内容1. 进程的创建与终止2. 进程的调度与优先级3. 进程同步与互斥4. 进程间通信四、实验步骤1. 进程的创建与终止(1)使用`fork()`函数创建子进程,通过比较返回值判断创建是否成功。
```cpid_t pid = fork();if (pid < 0) {perror("fork failed");exit(1);}```(2)使用`exit()`函数终止进程。
```cexit(0);```2. 进程的调度与优先级(1)使用`nice()`函数调整进程优先级。
```cnice(10); // 降低进程优先级```(2)使用`priority_seta()`函数设置进程优先级。
```cstruct sched_param param;param.sched_priority = 10;if (sched_setscheduler(pid, SCHED_RR, ¶m) == -1) { perror("sched_setscheduler failed");exit(1);}```3. 进程同步与互斥(1)使用`semaphore_t`类型的信号量实现进程同步。
```csemaphore_t sem;sem_init(&sem, 0, 1);sem_wait(&sem);// 执行临界区代码sem_post(&sem);sem_destroy(&sem);```(2)使用`mutex_t`类型的互斥锁实现进程互斥。
操作系统实验2——进程控制

实验2 进程控制一、实验目的加深对进程概念的理解,明确进程和程序和区别;进一步认识并发执行的实质;分析进程争用资源的现象。
二、实验内容1. 熟悉Linux进程控制常用命令。
2. 输入进程创建、控制的程序并调试程序。
三、实验预备知识1. 进程控制常用命令(1)ps 命令功能:查看目前的系统中有哪些进程,以及它们的执行情况。
常用命令格式及功能如下:ps 查看系统中属于自己的进程ps au 查看系统中所有用户的进程ps aux 查看系统中包含系统内部的及所有用户的进程主要输出列说明:USER:进程所有者的用户名PID:进程号TTY:进程从哪个终端启动TIME:此进程所消耗的CPU时间COMMAND:正在执行的命令或进程名称(2)top 命令功能:动态显示进程,实时监测进程状态。
与ps命令相似,只是top命令在执行后会以指定的时间间隔来刷新显示信息,以使top所显示的进程状态总是当前时刻的。
(3)kill 命令功能:结束或终止进程。
常用命令格式及功能如下:kill 5302 杀死PID为5302的进程kill -9 5302 强行杀死PID为5302的进程(4)echo $变量名功能:查看外壳变量的设定值。
例:echo $$ 显示当前进程PID2.常用系统调用函数常用系统调用函数、程序的说明、参数及定义如下:(1)fork()函数功能:创建一个新进程函数格式:int fork()其中返回int取值意义如下:小于0:创建失败0: 创建成功,在子进程中返回0值大于0: 创建成功,在父进程中返回子进程id值-1:创建失败(2)wait()函数功能:父进程等待子进程终止,以便对子进程进行善后处理。
函数格式:int wait(int *statloc)参数定义:statloc 指出子进程终止状态码的位置。
若不关心子进程的终止状态,可传递一个空指针。
返回值:正常返回时,为终止子进程的PID;错误返回时为-1;其他为0。
linux网络操作系统课程设计

linux网络操作系统课程设计一、课程目标知识目标:1. 理解Linux网络操作系统的基本概念,掌握其体系结构;2. 学会使用Linux命令行,熟悉常见网络配置与故障排除方法;3. 掌握Linux文件系统管理,了解文件权限与安全策略;4. 了解Linux下的网络服务与进程管理,理解系统启动流程。
技能目标:1. 能够独立安装与配置Linux操作系统,进行基本的网络设置;2. 熟练运用Linux命令行进行文件操作、权限管理及进程控制;3. 能够分析网络问题,利用Linux命令行工具进行故障排查;4. 学会编写简单的Shell脚本,实现自动化网络管理任务。
情感态度价值观目标:1. 培养学生对Linux网络操作系统的兴趣,激发探索精神;2. 培养学生的团队协作意识,学会分享与互助;3. 引导学生树立正确的网络道德观念,遵守网络安全规范;4. 培养学生的自主学习能力,养成良好的学习习惯。
本课程针对高年级学生,结合学科特点,注重理论与实践相结合。
在教学过程中,要求教师以学生为中心,关注个体差异,引导学生在实践中掌握知识,提高技能。
通过本课程学习,使学生具备一定的Linux网络操作系统应用与管理能力,为未来的职业发展打下坚实基础。
二、教学内容1. Linux操作系统概述- 系统特点与优势- 体系结构解析2. Linux命令行操作- 常用基本命令- 文件系统结构与命令- 权限管理命令3. 网络配置与故障排除- 网络接口配置- 路由与网关设置- 常用网络故障排除命令4. 文件系统管理- 文件与目录操作- 文件权限与归属管理- 磁盘空间管理5. 网络服务与进程管理- 常见网络服务原理与配置- 进程查看与管理- 系统启动流程与控制6. Shell脚本编程- 基本语法与结构- 常用命令与控制结构- 实例分析与编写本教学内容依据课程目标,按照系统性与科学性原则进行组织。
教学大纲明确各部分内容的教学安排,结合教材章节,确保学生能够逐步掌握Linux网络操作系统的相关知识。
linux教案_高校教学

Linux教案_高校教学一、课程简介1.1 课程背景Linux作为开源操作系统,在计算机领域具有广泛的应用。
本课程旨在让学生了解Linux操作系统的基本概念、掌握Linux常用命令及操作,并具备一定的Linux系统管理能力。
1.2 课程目标(1)了解Linux操作系统的基本概念及发展历程;(2)熟悉Linux文件系统结构;(3)掌握Linux常用命令及操作;(4)具备基本的Linux系统管理能力;(5)培养学生实际操作计算机的能力和团队协作精神。
二、教学内容2.1 教学资源教材:《Linux操作系统教程》实验环境:Linux服务器、学生机房2.2 教学安排(1)第1-2周:Linux基本概念及发展历程;(2)第3-4周:Linux文件系统结构及常用命令;(3)第5-6周:Linux文件权限与用户管理;(4)第7-8周:Linux进程管理及系统监控;(5)第9-10周:Linux网络配置与安全管理;(6)第11-12周:Linux常用服务器配置与运维;(7)第13-14周:综合练习与实战案例。
三、教学方法3.1 授课方式采用讲授、实验、讨论相结合的方式进行教学。
3.2 实验环节安排每次课后进行实验操作,巩固所学知识。
3.3 讨论与互动鼓励学生在课堂上提问、发表观点,教师引导学生进行讨论。
四、考核方式4.1 平时成绩(1)课堂表现:30%(2)实验报告:40%4.2 期末考试(1)理论知识:30%(2)实际操作:70%五、教学案例5.1 案例一:Linux系统安装与配置引导学生了解Linux系统的安装方法,学会使用Linux命令进行基本操作。
5.2 案例二:文件权限管理教授如何设置文件权限,掌握用户组管理及文件所有权概念。
5.3 案例三:进程管理讲解如何查看进程、杀死进程,以及进程优先级调整。
5.4 案例四:网络配置与安全管理引导学生配置Linux网络,了解网络安全策略。
5.5 案例五:Nginx服务器配置教授如何安装与配置Nginx服务器,实现网站的发布与访问。
Linux系统编程之进程控制(进程创建、终止、等待及替换)

Linux系统编程之进程控制(进程创建、终⽌、等待及替换)进程创建在上⼀节讲解进程概念时,我们提到fork函数是从已经存在的进程中创建⼀个新进程。
那么,系统是如何创建⼀个新进程的呢?这就需要我们更深⼊的剖析fork 函数。
1.1 fork函数的返回值调⽤fork创建进程时,原进程为⽗进程,新进程为⼦进程。
运⾏man fork后,我们可以看到如下信息:#include <unistd.h>pid_t fork(void);fork函数有两个返回值,⼦进程中返回0,⽗进程返回⼦进程pid,如果创建失败则返回-1。
实际上,当我们调⽤fork后,系统内核将会做:分配新的内存块和内核数据结构(如task_struct)给⼦进程将⽗进程的部分数据结构内容拷贝⾄⼦进程添加⼦进程到系统进程列表中fork返回,开始调度1.2 写时拷贝在创建进程的过程中,默认情况下,⽗⼦进程共享代码,但是数据是各⾃私有⼀份的。
如果⽗⼦只需要对数据进⾏读取,那么⼤多数的数据是不需要私有的。
这⾥有三点需要注意:第⼀,为什么⼦进程也会从fork之后开始执⾏?因为⽗⼦进程是共享代码的,在给⼦进程创建PCB时,⼦进程PCB中的⼤多数数据是⽗进程的拷贝,这⾥⾯就包括了程序计数器(PC)。
由于PC中的数据是即将执⾏的下⼀条指令的地址,所以当fork返回之后,⼦进程会和⽗进程⼀样,都执⾏fork之后的代码。
第⼆,创建进程时,⼦进程需要拷贝⽗进程所有的数据吗?⽗进程的数据有很多,但并不是所有的数据都要⽴马使⽤,因此并不是所有的数据都进⾏拷贝。
⼀般情况下,只有当⽗进程或者⼦进程对某些数据进⾏写操作时,操作系统才会从内存中申请内存块,将新的数据拷写⼊申请的内存块中,并且更改页表对应的页表项,这就是写时拷贝。
原理如下图所⽰:第三,为什么数据要各⾃私有?这是因为进程具有独⽴性,每个进程的运⾏不能⼲扰彼此。
1.3 fork函数的⽤法及其调⽤失败的原因fork函数的⽤法:⼀个⽗进程希望复制⾃⼰,通过条件判断,使⽗⼦进程分流同时执⾏不同的代码段。
实验二 进程管理(linux)

实验二进程管理(Linux)一、实验类型本实验为设计性实验。
二、实验目的与任务1)加深对进程概念的理解,明确进程和程序的区别。
2)进一步认识并发执行的实质三、预习要求1)进程的概念2)进程控制的概念及内容3)进程的并发执行4)熟悉互斥的概念5)用到的Linux函数有:fork(),lockf()等。
四、实验基本原理使用fork()系统调用来创建一个子进程,父进程和子进程并发执行,交替输出结果。
使用lockf()系统调用对临界区进行加锁操作,实现对共享资源的互斥使用。
五、实验仪器与设备(或工具软件)实验设备:计算机一台,软件环境要求: Linux操作系统和gcc编译器。
六、实验内容1)进程的创建编写一段程序,使用系统调用fork( ) 创建两个子程序。
当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。
运行程序10次,观察记录屏幕上的显示结果,并分析原因。
2)进程的控制修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。
如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程间的互斥,观察并分析出现的现象。
(1)进程的创建参考程序如下:#include<stdio.h>main(){int p1,p2;while((p1=fork())==-1); //p父进程p1子进程1if(p1!=0){while(((p2=fork())==-1); //p父进程p2子进程2if(p2==0) putchar('b');else putchar('c');}else putchar('a');}运行结果:略cab bca bac分析:原因:Fork()函数有三个返回值:1.-1 执行不成功2.0 表示当前正在执行子进程3.其他数值表示当前正在执行父进程,值是子进程的进程标识符PID4.获取当前进程的标识符getpid()5.获取当前进程的父进程的标识符getppid()(2)进程的控制参考程序如下#include<stdio.h>main(){int p1,p2,i;while ((p1=fork())==-1); // 父进程p,子进程p1if(p1==0){for(i=0;i<500;i++)printf("child_p1_ %d\n",i);}else{while((p2=fork())==-1);//父进程p,子进程p2if(p2==0)for(i=0;i<500;i++)printf("chind_p2_ %d\n",i);else for(i=0;i<500;i++)printf("father_p_%d\n",i);}}运行结果:略分析:由于函数printf()输出和字符串之间不会被中断,因此字符串内部的字符顺序输出不变。
操作系统课程设计Linux

操作系统课程设计Linux一、教学目标本课程的教学目标是使学生掌握Linux操作系统的核心概念、原理和应用技能。
通过本课程的学习,学生将能够:1.理解操作系统的基本原理,包括进程管理、内存管理、文件系统和输入/输出系统。
2.掌握Linux操作系统的安装、配置和管理方法。
3.熟练使用Linux命令行界面,进行日常操作和系统管理。
4.掌握Linux常用命令、 shell脚本编写和系统监控工具的使用。
5.了解Linux操作系统在服务器、嵌入式设备和云计算等领域的应用。
二、教学内容本课程的教学内容分为五个部分:1.操作系统概述:介绍操作系统的定义、功能和分类,以及Linux操作系统的历史和发展。
2.进程管理:讲解进程的基本概念、进程控制、进程同步和互斥、死锁及其解决方法。
3.内存管理:介绍内存分配与回收策略、内存保护、虚拟内存和分页分段机制。
4.文件系统:讲解文件和目录结构、文件访问控制、文件系统性能优化和磁盘空间分配策略。
5.输入/输出系统:介绍I/O设备管理、中断和DMA机制、设备驱动程序和I/O调度策略。
三、教学方法本课程采用多种教学方法相结合的方式,以提高学生的学习兴趣和主动性:1.讲授法:教师讲解操作系统的核心概念和原理,引导学生掌握基本知识。
2.讨论法:学生针对实际案例和问题进行讨论,培养学生的思考和分析能力。
3.案例分析法:分析Linux操作系统的实际应用案例,使学生了解操作系统的应用场景。
4.实验法:安排实验室课时,让学生亲自动手进行系统安装、配置和调试,提高学生的实践能力。
四、教学资源本课程的教学资源包括:1.教材:选用权威、实用的Linux操作系统教材,如《Linux操作系统原理与应用》。
2.参考书:提供相关的学术论文、技术博客和在线文档,供学生拓展阅读。
3.多媒体资料:制作课件、教学视频和演示文稿,辅助学生理解和记忆。
4.实验设备:提供Linux服务器、虚拟机和实验室环境,让学生进行实际操作。
linux期末课程设计

linux期末课程设计一、教学目标本课程的学习目标包括以下三个方面:1.知识目标:学生需要掌握Linux操作系统的基本概念、原理和常用的命令行操作。
具体包括Linux的历史、特点和常用发行版;文件系统结构;基本命令行操作;用户和权限管理;进程管理;网络配置和应用服务等。
2.技能目标:学生能够熟练使用Linux操作系统,进行日常的系统管理和维护工作。
具体包括文件操作、目录管理、文本处理、软件安装和更新、系统设置和网络配置等。
3.情感态度价值观目标:学生通过课程的学习,能够理解Linux开源精神的重要性,培养团队合作和分享的意识,提高自主学习和解决问题的能力。
二、教学内容本课程的教学内容主要包括以下几个部分:1.Linux概述:介绍Linux操作系统的起源、发展和特点,以及常用的Linux发行版。
2.文件系统:讲解Linux的文件系统结构,包括目录、文件权限和文件操作命令等。
3.命令行操作:深入学习Linux的命令行操作,包括基本命令、文本处理命令和软件包管理命令等。
4.用户和权限管理:介绍Linux的用户管理、组管理和文件权限控制等知识。
5.进程管理:讲解Linux的进程概念、进程控制命令和进程监控工具等。
6.网络配置:包括网络配置命令、网络文件共享和远程登录等知识。
7.应用服务:介绍Linux下的常用服务,如Apache、MySQL和Samba 等。
三、教学方法本课程采用多种教学方法,以激发学生的学习兴趣和主动性:1.讲授法:讲解Linux的基本概念、原理和命令操作。
2.案例分析法:通过实际案例,引导学生学会解决实际问题。
3.实验法:安排实验课,让学生亲自动手操作,加深对知识的理解和记忆。
4.小组讨论法:学生进行小组讨论,培养团队合作和沟通能力。
四、教学资源本课程的教学资源包括以下几个方面:1.教材:选用权威、实用的Linux教材,为学生提供系统的学习资料。
2.参考书:提供丰富的参考书籍,方便学生深入研究。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
课程设计报告课程名称Linux操作系统课程设计指导教师张玲起止日期2014-03-01 至2014-06-13实验项目实验二进程控制学院信息与通信工程学院专业电子信息工程学生姓名班级/学号成绩指导老师签字1. 课程设计概述本次课设意在利用进程控制相关的系统调用编程进行进程控制实验,观察进程从创建、运行到终止的控制过程,加深对进程概念的理解。
1.1 课程设计的目的本实验的目的是掌握进程的概念,理解进程的创建、执行、等待、终止的过程。
熟悉有关进程控制的命令和系统调用,理解Shell 的工作原理。
1.2 课程设计的内容1) 进程控制命令● 使用进程控制命令ps ,kill 监视和控制进程的活动2) 编程部分● 用fork ,wait ,exec 系统调用编程实现进程控制;● 编写一个简单的shell 。
1.3 设计原理进程是一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源。
构建的文件构架如图:图1 实验目录树的结构 2012010948exp2 exp1 exp3vis vis22.实验步骤2.1操作2.1.1进程控制命令(在此终端窗口的操作截图见图1)1.执行ps命令,查看bash进程的PID:PID就是各进程的身份标识,程序一运行系统就会自动分配给进程一个独一无二的PID。
进程中止后PID被系统回收。
2.在后台运行一个yes进程:yes > /dev/null &3.用ps -f命令观察yes进程的pid和ppid,用ps u命令观察yes进程的状态。
yes进程的父进程是哪个进程?通过查看yes程序的PPID可知其父进程为bash4.根据命令名搜索特定的进程:ps-ef|grep yes:5.用kill命令杀掉yes进程:kill 【PID】:图1 进程控制命令2.1.2进程控制系统调用(此部分操作截图见图2、3)1.利用fork()和wait()来控制进程的执行:♦在exp2目录下编写一个程序fork_wait.c。
该程序用fork创建了一个子进程,而后子进程先输出自己的信息,再睡眠10秒后结束。
父进程等待子进程,收集到子进程结束信息后输出信息,然后结束。
编译:gcc-o fork_wait fork_wait.c 运行:./fork_wait♦修改此程序,使父进程先睡眠一段时间,然后再收集(wait)子进程。
重新编译并在后台运行该程序(./fork_wait &),在子进程已终止而父进程尚未收集它时,用ps u观察子进程的僵尸状态。
在父进程分支的开始处调用函数sleep(40)睡眠40秒。
用ps u可以看见一个Z2.利用exec()置换程序的执行代码文件:♦在exp2目录下编写一个程序exec_test.c,使子进程执行另一个程序,如echo。
编译:gcc-o exec_test exec_test.c 运行:./exec_test♦修改程序exec_test.c,使子进程执行一个可持续运行一段时间命令,重新编译并在后台运行程序(./exec_test &),用ps -f 命令观察子进程执行的命令名CMD。
添加一句sleep 40。
即:execl("/bin/sleep", "sleep", "40", NULL);图2 进程控制系统调用-fork_wait图2 进程控制系统调用-fork_wait2.1.3Mini Shell编程(此部分操作截图见图4、5)1.在exp2目录编写一个简单的shell程序—Mini Shell,它接收输入的命令并解释执行。
♦Linux的命令分为内部命令和外部命令两种。
内部命令由Shell程序自己实现,如cd、pwd等,外部命令是位于磁盘上(多数在/bin和/usr/bin目录下)的可执行程序。
Mini Shell只实现两个内部命令:pwd和quit(退出),它可执行所有不带选项和参数的外部命令,如date、who、cal、ls等。
2.(选做1)修改Mini Shell程序,使它可执行只带一个命令选项或参数的命令行,如ls -a、cat file、echo hello等。
♦用strtok函数将读入的命令行cmd以空格为分隔符拆为两个字符串cmd1和cmd2:cmd1=strtok(cmd," ");cmd2=strtok(NULL," ");此时的cmd1即为命令名,cmd2即为命令的选项或参数。
判断cmd2,若为空则执行系统调用execlp(cmd1, cmd1, NULL),否则执行execlp(cmd1, cmd1, cmd2, NULL)3.(选做2)修改Mini Shell程序,可做任何你认为可以改进的修改,如界面、提示、处理输入错误、增强功能等。
图4 Mini Shell编程-1图5 Mini Shell-2图6 Mini Shell-33.实验结论与评价3.1进程控制命令此部分操作较为简单,主要在帮助理解进程的概念和进程的PID,掌握基本的进程操作如ps kill 和后台运行一个程序等。
通过这一部分的操作我了解到进程是什么,进程和程序有什么不一样,子进程和父进程之间的关系。
3.2进程控制系统调用fork_wait是本次实验的第一个编程题,通过已经给好的代码我了解到了几个在Linux中常用的函数,如sleep(),getpid(),fork(),wait() 等,我更加清晰地在修改程序的过程中理解了子进程和父进程的关系,更重要的是我学会了通过简单函数来对进程进行控制。
观察到了特殊的僵尸进程:僵尸进程(zombie)是指已终止运行,但尚未被清除的进程。
exec_test是本次试验的第二个编程题,这次学习到的函数是execl(),第一参数path字符指针所指向要执行的文件路径,接下来的参数代表执行该文件时传递的参数列表:argv[0],argv[1]... 最后一个参数用空指针NULL作结束。
利用这个函数实现了用exec()置换程序的执行代码文件的功能。
3.3Mini Shell编程这一部分的操作较为复杂,占用了实验的大部分时间。
让我意识到我们的编程能力还有待提高,尤其是字符串、文件等部分。
选作一的地方通过空格把命令名和参数分开分别执行,需要分清是应该先读命令再分开还是先分开再读命令,选作二我增添了几个Mini Shell内部命令,修改了界面。
4.程序清单4.1fork_wait.c#include <stdio.h>#include <stdlib.h>#include <unistd.h>main(){int rid, cid;printf("****fork-test by 2012010948****\n"); //将your-sid改为你的学号rid = fork();if ( rid < 0 ) printf("error in fork!");else if ( rid == 0 ) { // 子进程printf("I am child, my PID is %d. I will sleep a while.\n", getpid());sleep(10); // 睡眠10秒printf("I am down.\n");}else { // 父进程//sleep(30); //睡眠30秒cid=wait(NULL);printf("I am parent, I caught a child with PID of %d.\n", cid);}exit(0);}}4.2exec_test.c#include <stdio.h>#include <stdlib.h>#include <unistd.h>main(){int rid;printf("****exec-test by 2012010948****\n"); //将your-sid改为你的学号rid = fork();if ( rid < 0 ) printf("error in fork!");else if ( rid == 0 ) { // 子进程printf("I am child, I will change to echo!\n");execl("/bin/echo", "echo", "Hello! ", NULL);}else wait(NULL); // 父进程exit(0);}4.3mini_shell.c#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>void pwd();main(){int id;char cmd[80];printf("****mini-shell by your-sid****\n"); //将your-sid改为你的学号while(1) {printf("Mini Shell> "); //显示命令提示符fgets(cmd, 80, stdin); //从键盘读入命令行cmd[strlen(cmd)-1]=0; //将行尾字符置为字符串结束符0if ( strcmp(cmd, "quit") == 0 ) exit(0); //内部命令quitif ( strcmp(cmd, "pwd") == 0 ) pwd(); //内部命令pwdelse { //外部命令id=fork();if (id<0) { printf("Fork error!\n"); exit(1);}if ( id == 0 ) {if (execlp(cmd, cmd, NULL)<0)printf("Command error!\n");exit(2);}wait(NULL);}}}void pwd(){char dir[50];getcwd(dir,50);printf("%s\n", dir);}4.4mini_shell.c选作一#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>void pwd();main(){int id;char cmd[80];char* cmd1;char* cmd2;char* cmd3;char y;printf("2012010948\n"); //将your-sid改为你的学号printf("Thank you for using me. Do you want any help?(y/n)");getchar();scanf("%c",&y);if(y='n')printf("thanks");else if(y='y')printf("ok");while(1) {printf("Mini Shell> "); //显示命令提示符fgets(cmd, 80, stdin); // 从键盘读入命令行cmd[strlen(cmd)-1]=0; //将行尾字符置为字符串结束符0cmd1=strtok(cmd," ");cmd2=strtok(NULL," ");cmd3=strtok(NULL," ");if ( strcmp(cmd1, "quit") == 0 ) exit(0); //内部命令quitif ( strcmp(cmd1, "pwd") == 0 ) pwd(); //内部命令pwdelse { //外部命令id=fork();if (id<0) { printf("Fork error!\n"); exit(1);}if ( id == 0 ) {if(cmd2!=NULL){ if(cmd3==NULL){if (execlp(cmd1, cmd1, cmd2,NULL)<0)printf("Command error!\n");exit(2);}else{if (execlp(cmd1, cmd1, cmd2,cmd3,NULL)<0)printf("Command error!\n");exit(2);}}else{if (execlp(cmd1, cmd1,NULL)<0)printf("Command error!\n");exit(2);}}wait(NULL);}}}void pwd(){char dir[50];getcwd(dir,50);printf("%s\n", dir);}4.5mini_shell.c选作二#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>void pwd();main(){int id;char cmd[80];char *cmd1;char *cmd2;printf("********************************\n");printf("****mini-shell by 2012010948****\n"); //将your-sid改为你的学号printf("********************************\n");while(1) {printf("Mini Shell> "); //显示命令提示符fgets(cmd, 80, stdin); //从键盘读入命令行cmd[strlen(cmd)-1]=0; //将行尾字符置为字符串结束符0printf("%s\n", cmd);cmd1=strtok(cmd," ");cmd2=strtok(NULL," "); //将命令行分开成两部分if ( strcmp(cmd, "quit") == 0 ) exit(0); //内部命令quitif ( strcmp(cmd, "where") == 0 ) pwd(); //内部命令pwdif ( strcmp(cmd, "tired") == 0 ) {sleep(5); printf("i'm down\n");} //内部命令pwd else { //外部命令id=fork();if (id<0) { printf("Fork error!\n"); exit(1);}if ( id == 0 ) {if(cmd2==NULL) execlp(cmd1, cmd1, NULL);else execlp(cmd1, cmd1, cmd2, NULL);if (execlp(cmd, cmd, NULL)<0)printf("Command error!\n");exit(2);}wait(NULL);}}}void pwd(){char dir[50];getcwd(dir,50);printf("%s\n", dir);}参考文献[1]张玲. Linux操作系统基础、原理与应用,北京:清华大学出版社,2014年2月。