操作系统课程设计

发布 2022-10-05 11:22:28 阅读 4331

课程设计。

题目shell编程。

学生姓名汪国新学号 2009112110

专业计算机科学与技术班级 20091121

指导教师张老师。

完成日期 2012 年 1 月 8 日。

—编写一个简单的shell程序。

本文简单的给出了一个shell的模拟实现,读者可以从中了解到怎么获取当前登录系统的用户的用户名,当前的主机名和当前用户正处在的当前路径名。读者还可以知道怎么从终端读取命令,怎么解析命令和怎么执行命令以及实现所使用的相关数据结构和算法。另外,读者还可从文中学习到管道,重定向,后台运行的实现思想。

操作系统提供两种基本用户接口:第一种是程序接口,以函数(系统调用)的形式向程序员提供支持,通过fork()、read()、write()等函数为上层软件提供服务,函数是用户应用程序与操作系统之间的一种接口;第二种是命令接口,当用户在控制作业运行、浏览文件信息和访问硬件资源时,使用此接口和操作系统进行交互。shell为用户和操作系统之间的命令交互提供最基本的接口,在使用者和操作系统之间架起一座桥梁,它的名字shell(外壳)形象地表示它在用户与操作系统内核之间的关系。

早起shell主要是用作命令解释器。经过不断的扩充和发展,现在已是命令语言、命令解释器、程序设计语言的统称,被泛指为一个提供人机交互界面和接口的程序。

最简单的shell程序是基于字符的,用户通过输入一个字符串到shell中来与操作系统进行交互,并且操作系统的响应结果是输出一行行的字符到屏幕上,更方便的shell程序使用图符bourne shell演变而来的。

文中设计并实现了一个简单的交互式shell——myshell。myshell简单的实现支持程序后台运行、支持重定向、支持管道、支持设置搜索路径、支持内置命令(cd:切换目录,exit:

退出shell,path:设置所搜路径)等一些功能。

图1 myshell总体结构图。

说明:此shell模拟程序就如同shell一样提供了一个用户和机器之间进行交互的交互界面,此界面是一个字符的界面,用户从字符界面终端敲入命令来使用计算机。对于用户键入的命令,首先就要通过命令解析程序来解释用户的这条命令是干什么的,只有计算机知道了用户的命令是具体干什么的才能去实施执行,命令解析程序也就是分析用户的命令,了解用户的命令到底是内部命令呢还是自己定义的存放在可执行命令文件中的命令。

如果命令是用户自定义的命令,那么,命令解析程序还需要分析命令是管道命令还是i/o重定向命令,另外就是命令是否后台执行。通过命令解析程序,那么计算机已经知道了用户的命令是要干什么的了,于是就是执行命令了,如果命令是内部命令,就直接调用内部命令去执行,如果命令是用户自定义的命令,那么就创建一个子进程去执行用户的命令。所以,此shell模拟程序也就应该有交互界面、命令解析、运行内部命令、运行可执行命令文件、创建子进程、i/o重定向、创建管道等功能模块。

图2 程序总流程图。

说明:此shell模拟程序开始之后第一步工作就是进行一些简单的初始化工作,在初始化时获得当前登录到系统的用户名、当前机器的主机名、当前正处在的路径的路径名。接着第二步工作就是根据第一步中获得的信息打印命令提示符创建一个与用户交互的交互界面。

第三步工作就是读取用户命令了,如果用户的命令是exit,那么就直接退出模拟程序,如果用户的命令不是exit,那么就进入第四步——命令解析,通过解析用户命令了解了用户命令是干什么的以及怎么干之后就进入第五步具体的实施执行用户的命令了。执行一条命令结束之后就又进入第二步打印命令提示符,开始读取用户下一条命令了。如此循环执行。

为了实现此shell模拟程序的功能,当然很多数据结果是必须的。在此shell模拟程序中,主要用到的数据结构有以下几个:

1)数据结构1

struct

char cmdline[cmdlinelen用于存储整个命令行*/

char *typenull表示普通命令,指向cmdline中’|’表示管道命令*/

char *runtypenull表示前台运行,指向cmdline中’&’表示后台运行*/

int pos命令行当中正在处理的字符的位置*/

commandline= ,null,null,0};

此数据结构中的域cmdline用户存储接收到的用户命令。type域用指明当前的命令是一般的命令还是管道命令,如果type为null就说明当前的命令是普通命令;如果type指向域cmdline中的’|’就说明是管道命令。runtype域指当前的命令是前台运行还是后台运行,如果run_type为null就说明此命令是前台运行;如果run_type指向域cmdline中的’&’就说明此命令是后台运行的。

pos域用于在解析命令时指明当前正在处理的字符位置。

在整个程序中只需要使用其一个实例就可以了,于是就没有给这个数据结构一个名字。在定义这个数据结构的同时就定义了一个这个数据的全局变量实例commandline。每当读取用户命令之前就将cmdline域清空,用于存放将要读取的用户的下一条命令。

另外,还要将type、run_type、pos分别置成null、null、0,消除处理上一条命令的干扰。

2)数据结构2

struct command

char cmd[cmdlen用于存放解析出来的单纯的命令*/

int argc用于存放参数个数*/

char *ar**[argnum用于存放各个参数的首地址*/

char *infd用于指出输入重定向的位置*/

char *outfd用于指出输入重定向的位置*/

struct command *next; /用于连接管道中的下一条命令的struct command 结构*/

struct command主要用在解析命令时,cmd域用于存放解析出来的命令,单纯的命令。argc域用于指明参数的个数。ar**用于存放各个参数的首地址。

如果是重定向命令,infd域和outfd域就分别用来指明输入重定向和输出重定向的位置。如果当前的命令是一条管道命令,那么next域就用于连接管道的下一条命令的struct command结构。

当然,每当上一条命令执行完成之后在将要读取下一条用户命令之前,要将上一条命令中用到的struct command实例所占的内存空间释放。

3)数据结构3

struct

/*定义一个光标结构体,用于描述当前的插入点*/

char *base; /光标的基位置*/

char *pos; /光标的当前位置*/

int range; /光标的活动域*/

int offset; /光标当前的偏移量*/

cursor=;

命令是一个字符一个字符的解析的,当解析到某一个字符时,当前的字符是命令,还是参数,或者还是管道指示符,再或者还是重定向指示符等,应该归类放到那里去,这是就需要知道插入点,光标结构体就是用于只是当前的插入点位置的。base域指明当前光标的基位置。例如,当前解析到的是参数,正在往一块存放参数的内存中存放,那么base就于指向当前正在存放参数的内存的首地址。

pos域就用于指向当前正在放入字符的内存位置。range域就用于指示当前光标可以活动的范围,如果光标的当前偏移量超出了光标的活动范围,那么就发生了内存溢出。offset域就用于指出当前贯标的偏移量。

光标结构体和前面的命令行的结构体一样,在整个程序中只需要使用到此结构体的一个实例即可,于是也是没有给这个结构体一个名字。在定义此结构体的同时就定义了此结构体的一个全局变量实例cursor。同前面一样,每当在将要读取下一条用户命令之前就复位光标,将base和pos置成null,range和offset置成0。

4)数据结构4

char *username,*hostname,*currentpath;

char *类型的全局变量username、hostname、currentpath分别用于指向当前登录到系统的用户的用户名,当前的主机名,当前在处在的路径的路径名。

5)数据结构5

char path[pathlen];

char类型全局数组path用于记录当前的搜索路径。

6)数据结构6

struct command *head = null;

全局struct command结构体变量用于指向从每条用户命令中解析出来的第一条命令的命令结构体struct command。当然在读取每一条用户命令之前要置成null。

7)说明。对于以上数据结构定义中用到的cmdlinelen、cmdlen、argnum等都是一些宏定义。在此程序中,给出了如下的一些宏定义:

#define hostnamelen 20

#define pathlen 100

#define cmdlinelen 100

#define cmdlen 50

#define argnum 8

#define arglen 100

图3 初始化流程图。

说明:初始化的函数声明为void init(),初始化开始后就是获取username,使用函数getlogin(),将获取的username的首地址存放于全局char *类型的变量username中。接着就是获取hostname,使用函数gethostname(hostname,hostnamelen)将获取到的hostname的首地址存放于全局char *类型的变量hostname中。

再就是获取currentpath,使用函数getcwd(currentpath,pathlen)将获取到的currentpath的首地址存放于全局char *类型的变量currentpath中。最后就是用自定义函数void set_path(char *newpath)设置默认搜索路径后结束void init()返回了。

操作系统课程设计

课程设计 河北大学工商学院。装。订。线。操作系统课程设计。题目 操作系统课程设计 学院工商学院 学部信息科学与工程 专 操作系统课程设计。题目 操作系统课程设计 学院工商学院 学部信息科学与工程 专业计算机类 学号 姓名。指导教师。年 6 月 24 日。设备管理 2 2.1设计任务2 2.2设计要求...

操作系统课程设计

银行家算法模拟。系别 班级 组员 银行家算法模拟。1.课程设计目的。通过本次课程设计,加深对最经典的避免死锁的银行家算法的理解,掌握死锁形成必要条件 安全状态等概念的理解,通过用c语言编程模拟该算法,并在windows平台上实现,更好地掌握操作系统的原理及实现方法。2.任务及要求。设n为系统进程的个...

操作系统课程设计

学生实习实训报告。实习类型 操作系统课程设计 学号 0901110005 学生姓名 田兴杰 指导教师 曹春梅 专业班级 信息安全技术0901班 院 部 电子信息系 2011年 1 月 7日。实习实训成绩评定表。目录。目录3 摘要4关键字4 1.1虚拟机简介5 1.1.1 一般意义的虚拟机5 1.1....