




已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第章绪论1.1 引言1.1.1 选题的背景本次课程设计是在学习完了现代操作系统课程之后做的,本人选择了编写命令解释器模拟shell功能问题题目来实现。1.1.2设计思路和预期目标通过对现代操作系统的学习,我预计将用命令分割得到命令和参数,通过fork()函数创建子进程调用exec系统函数,并自己编写无法用exec系统函数执行的cd命令函数,依次完成打开提示符,获取用户输入的指令可解析指令、可寻找命令文件、可执行基本的命令的功能。1.2 课程设计目的与意义通过学习Linux下的系统调用、进程和进程间的通信,我基本了解内核的外围部分是如何合理的分配各种资源来使各类应用程序正常工作的。通过编写shell命令解释器,可以练习熟练使用系统调用和各类IO库函数。进行shell编程,对于一个嵌入式工程师来说做shell编程是一个基本工,是做好嵌入式开发的前提。1.3 课程设计内容与要求可以打开提示符,获取用户输入的指令可解析指令、可寻找命令文件、可执行基本的命令的功能。 1.4 课程设计地点及设计环境课程设计地点:图书馆五楼软件实验室课程设计环境:Red hat Linux系统开发环境:Linux 开发平台第章 系统设计2.1 系统框架设计2.1.1 系统主结构图图1 函数调用结构图execvp()图2 进程调度结构图2.1.2 函数流程图本程序除系统函数外还有三个重要函数main()、CD()、str_cut(char *p,char *buf)。其中main()函数流程图如图3,CD()函数流程图如图4,str_cut(char *p,char *buf)函数流程图如图5。图3 主函数流程图图4 命令裁剪函数流程图图5 CD函数流程图2.2 系统模块功能说明2.2.1 主模块说明主函数完成读命令,调用各其它函数,创建子进程,在子进程调用exec执行,提示错误等功能。首先,申请一个buff的字符串数组,用来存放命令,另外申请一个pid_t型的变量来存放新生成的子进程的IP号。pid_t是Linux里的一个宏定义,通常可以当作一个整形看待,但为了便于移植程序,因为不同类型的计算机对整形长度的定义是不同的,在嵌入式里,不同的嵌入式处理器的运算位数不同,数据类型的定义也不同。然后,进入一个死循环,打印出提示符当前路径。完成这一功能依赖的是char *get_current_dir_name()这一系统函数调用。要注意的是这个函数虽然加了头文件,但在使用前要声明。或者定义#define _GNU_SOURCE。因为unsigned long 和 char* 都是16位 把返回的char * 当成了unsigned long 需要用_GNU_SOURCE 来声明一下,这个宏是用来声明ISO POSIX 之类的标准,就可以区分返回值是char * 和 unsigned long了。接下来,读取命令,这里我用的是fgets函数,之所以不用scanf函数来读字符串,是因为它以空格为结束标志,这样参数就无法读入了。之后是if句子是用来做退出用的,如果敲入的是“exit”那么就退出循环,结束整个程序。 然后还有一个if语句是用来判断是不是cd命令,而决定是否调用cd函数。这两个if语句的位置很重要,在编程初期,我将它放在了下面创建的子进程中,出现了一些问题。比如,当cd()命令执行时地址制定错误后,提示语Change dir error!n会出现两次。原因是当执行“exit”“cd”时子进程中不需要执行exec函数,也就是说子进程没有被替代,它一直与父进程保持一致。所以出现了以上代码会执行两次的现象。所以这两个if语句的语句必须放在子进程外。下面就是创建了一个子进程,子进程的IP号放到pid里,其中父进程得到了子进程的IP号,子进程里得到0;这样,子进程执行if里的代码,父进程执行else里的代码;特别要指出的是子进程里,execlp使buff里的命令执行,这个子进程的代码都被命令文件的代码替换了,子进程在exec结束时已经结束,所以成功执行时后面的错误提示代码是不被执行的。当这个命令不存在时,不会将剩余代码替换,他会继续执行下面的代码,即打印一句提升:“command not found!”不让程序限于阻塞。父进程里,通过得到的子进程的IP号,来使用wait函数等待子进程的退出,接着进入下一次循环,打印提示符,等待命令的再次输入。2.2.2 子模块说明1、切割函数剪切的方式取决于调用的exec函数所需要的参数形式。execl(执行文件) 相关函数 fork,execle,execlp,execv,execve,execvp调用方式分别为:main()execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char * )0);main()execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char *)0);main()char * argv =“ls”,”-al”,”/etc/passwd”,(char*) ;execv(“/bin/ls”,argv);main()char * argv =“ls”,”-al”,”/etc/passwd”,(char *)0;char * envp =“PATH=/bin”,0execve(“/bin/ls”,argv,envp);main()char * argv = “ls”,”-al”,”/etc/passwd”,0;execvp(“ls”,argv);由上可知execvp()函数调用最简单易用,且切割方便。第一个参数为命令文件名,第二个参数为一个指针数组,这样就可以把命令和参数全部丢给执行函数。为此我们也为切割函数设置一个是原命令字符串指针buf1,一个是存储字符串指针的字符串指针buf2。切割函数将完成以下功能。将buf1中的空格全部置换为“0”,它有很多作用。其一,在把buf1作为execvp()第一个参数时,读取命令后会自动停止,因为命令与参数之间的空格已经变为结束符。其二,在把buf2作为第二个参数时,按指针寻址后,避免了一次读取到多个参数的现象。最后一位的n换成0,即buf1和buf2最后一个单元置空,以符合参数形式要求。2、 CD函数命令分为两种,一种为内部命令,一种为外部命令。用户输入的命令是执行存储在文件系统下中的可执行程序,我们称之为外部命令或外部程序。外部命令的形式是一系列分隔的字符串。第一个字符串可以是可执行程序的名字,其它的是传递给这个外部程序的参数。如果第一个字符串所声名的可执行文件并不存在或者不可执行,则认为这个命令是错误的。以上其它命令就是外部命令,因而可以用exec系统文件函数完成执行。但是cd命令和exit命令是内部命令,不能用exec函数执行的,它的出现时shell特有的功能。所以在这里,cd函数也是我自己编写的。它的功能有两个,其一是判断路径的正确性,其二是执行变换路径函chdir()。第章源程序代码设计11#include #include #include #include #include char *get_current_dir_name(); void str_cut(char *p,char *buf) int i=0; /i即为buf数组下标 int u=0; /u是一个标志位,u=0,表示前一字符为空格或无字符/即刚开始;u=1,表示前一字符为字母 while(*p) /p为原字符串指针,*p不为0则继续循环 if(*p= ) *p=0; /把空格替换为结束符 p+; u=0; /标志位u清零 else if(u=0) bufi+=p+; /单词的首地址赋给buf u=1; /标志位u置1 else p+; /什么也不做,p指向下一个 bufi=NULL; /buf里最后一个地址是空便于execvp使用void CD(char argv1) int res=0; if(argv1!=NULL) res=chdir(argv1); if(res0) printf(Change dir error!n);int main(void) char buf150; char *buf210; pid_t pid; char *p; while(1) p=get_current_dir_name(); printf(%s#,p); fgets(buf1,sizeof(buf1),stdin); buf1strlen(buf1)-1=0; str_cut(buf1,buf2); /调用上面的切割函数,原字符串仍存在/ buf1里,其分割后地址存在buf2里 if(strncmp(buf1,exit,4)=0) break; if(strncmp(buf1,cd,2)=0) CD(buf21); continue; if(pid=fork()=0) execvp(buf20,buf2); printf(command not found!n); /命令不可执行,则向下走 /打印无此命令 exit(1); else waitpid(pid,NULL,0); exit(0);第章系统的调试和运行本系统可以执行目录命令、文件命令,带参数和不带参数命令均可正确执行。并且有检错功能,伴有各类错误提示。“ls”“pwd”“mkdir”“rmdir”“cd”“mv”等不带参数的目录操作命令可以正常执行,结果如图6。“ls l -a”“mkdir p 电路/数电”“rmdir p 电路/数电”“cd /root”等带参数甚至多参数目录命令可以正常执行,结果如图7。“cat”“more”“cp”“rm”“vi”“gcc”等命令无论有无参数也均可正常执行,结果如图8。其中vi编辑情况如图9。本程序有比较好的健壮性,不会阻塞,且有各类错误提示,如图10。内部命令“exit”执行结果如图10。图6 无参数目录命令执行图图7 有参数目录命令执行图图8 文件操作命令执行图图9 vi插入数据图图10 错误提示及退出执行图通过各类数据的测试包括不同命令、不同参数、不同参数数量以及错误命令的测试,可以证明,本程序属于一个功能完善,健壮性强的作品。结 论本次操作系统课程设计我选择的命令解析器模拟shell的问题是通过Linux操作系统实现,使我对Linux系统有了一些了解,并在课程设计过程中得到进一步深化,特别是对Linux下各种命令及其系统文件调用方式方法。巩固了我的操作系统的理论,提高了我使用linux C的能力。本程序有很多创新点,它是一步步完善,一步步升级的。在第一阶段,它只有输入不带参数的简单命令(不包括cd命令),使用的是scanf()读取字符,以空格结束命令。用execlp()调用系统文件函数。第二阶段增加创新点,用fgets ()获取命令字符串,它以回车为结束标志,使得空空格分隔命令和参数时也可以整条命令存入字符串。用execvp()调用系统文件函数,使得可以传入多条参数,且参数数量可以不固定。并按其参数要求设计切割函数切割方式。第三阶段在发现了cd命令执行报错后,查看相关资料发现cd不属于外部命令,不能用exec函数调用,之后我自己编写了CD()函数。第四阶段在全面功能测试时我发现cd命令输入错误路径后的错误提示输出了两遍。在仔细分析研究之后我发现了错误。在子进程没有调用exec函数前,父进程与子进程是一模一样,调用后子进程才被替代,即调用前所有代码执行两遍,造成了提示的重复。改正方法,充分考虑代码运行对子进程的依赖程度,没有依赖性的调出子进程,只在父进程中运行。通过这个从简到繁,逐步扩展的过程基本程序才得以完成,通过发现问题解决问题的过程,程序才得以逐步完善。里面融合这我每一点的创新观念。经过测试已经证明本程序有很强的功能和很好的性能,但是仔细观察模拟shell和真实shell的区别还是可以发现。比如说文字变色功能,在shell中,浏览目录时文本和文件夹名称显示颜色不同,vi编辑器中,输入C语言的关键字等会自动变色提示。而在模拟shell中,所有输出均为黑色。又如在真实shell中,存在很多快捷键,像向上向下键可以重复已经输入过的命令,向左向右键可以移动光标,而在模拟shell中,摁这些键则会认定为是录入字符。这些证明真实的shell功能是更复杂更完善的,我的程序还有很多需要改进的地方,以后要继续学习,继续完善。为了完成本次试验,我参看了很多文献,我学到了很多新的东西,比如调用系统文件的函数种类和用法,比如用户可以调用内核文件的原因、范围和途径,比如头文件、宏定义、函数声明的配合使用,再比如创建子进程的目的,需要通过子进程完成的操作,父进程与子进程之间的关系,并且在学习之后把它们运用的了实践之中。源代码虽然很少但搜寻、学习、尝试应用相关知识的过程却是非常复杂。我也从中发下了自己不懂得专业知识实在太多,有一种井底之蛙的感觉。我以后一定要拓宽自己的知识面。 我在此还要特别的感谢那些在网上分享自己的学习心得经验的人,我是在解读了各个版本的作品后形成的自己的思路。我要感谢那网上讲解各种疑难问题的人,在他们讲解下,我解决了很多从没遇到过的问题。我还要感谢给予我指导和帮助的同学和老师。程序使用说明书1显示工作目录命令名称:pwd - print name of current/working directory命令格式:pwd-help-version功能说明:执行pwd指令可显示当前所在的工作目录的绝对路径名称。命令参数:-help在线帮助。-version显示版本信息。范例:显示当前工作目录。llylocalhost $ pwd/home/llyllylocalhost $2改变当前目录命令名称:cd - change diretory命令格式:cd -L|-P dir功能说明:改变当前目录为dir指定的目录。其中dir可为绝对路径或相对路径。若目录名称省略,则变换至用户的 home directory (也就是刚 login 时所在的目录)。 另外, 也表示为 home directory 的意思,. 则是表示目前所在的目录,. 则表示目前目录位置的上一层目录。 范例:(1)进入/home目录。llylocalhost $ cd /homellylocalhost home$(2)进入根目录。llylocalhost $ cd /llylocalhost /$(3)进入用户lly的主目录。llylocalhost /$ cd llylocalhost $或者:llylocalhost /$ cd /home/llyllylocalhost $(4)进入当前目录的上一级目录。llylocalhost $ cd .llylocalhost home$3显示目录内容命令名称:ls - list directory contents 命令格式:ls OPTION. FILE.功能说明:显示指定工作目录下的内容(列出当前工作目录所包含的子目录名称或文件名称)。 命令参数:-a 显示所有文件及目录 (包括隐藏文件,隐藏文件以“.”开头) -l 除文件名称外,亦将文件型态、权限、拥有者、文件大小等信息详细列出 -r 将文件以相反次序显示(原定依英文字母次序) -t 将文件依建立时间先后次序列出 -A 同 -a ,但不列出 . (目前目录) 及 . (父目录) -F 在列出的文件名称后加一符号;例如可执行文件则加 *, 目录则加 / -R 若目录下有文件,则其下的文件也按次序列出范例:(1)列出目前工作目录下的内容。llylocalhost $ lsDesktop Documents Download Music Pictures Public Templates Videosllylocalhost $(2)列出当前目录的详细内容。llylocalhost $ ls -ltotal 64drwxr-xr-x 2 lly lly 4096 2009-05-02 17:43 Desktopdrwxr-xr-x 2 lly lly 4096 2009-05-02 17:18 Documentsdrwxr-xr-x 2 lly lly 4096 2009-05-02 17:18 Downloaddrwxr-xr-x 2 lly lly 4096 2009-05-02 17:18 Musicdrwxr-xr-x 2 lly lly 4096 2009-05-02 17:18 Picturesdrwxr-xr-x 2 lly lly 4096 2009-05-02 17:18 Publicdrwxr-xr-x 2 lly lly 4096 2009-05-02 17:18 Templatesdrwxr-xr-x 2 lly lly 4096 2009-05-02 17:18 Videosllylocalhost $(3)列出目前工作目录下的内容,包括隐藏文件。llylocalhost $ ls -a. .esd_auth .ICEauthority .thumbnails. .fontconfig .kde .tomboy.bash_history .gconf .local .tomboy.log.bash_logout .gconfd .metacity .Trash.bash_profile .gimp-2.4 Music Videos.bashrc .gnome .nautilus .wapi.config .gnome2 Pictures .xsession-errorsDesktop .gnome2_private Public .zshrc.dmrc .gstreamer-0.10 .pulse-cookieDocuments .gtk-bookmarks .recently-used.xbelDownload .gtkrc-1.1-gnome2 Templatesllylocalhost $4创建目录命令名称:mkdir - make directories命令格式:mkdir OPTION DIRECTORY.功能说明:建立名称为DIRECTORY.的子目录。命令参数:-p 确保目录名称存在,不存在的就建一个。范例:(1)在当前目录下建立一个名为Game的子目录。llylocalhost $ mkdir Gamellylocalhost $ lsDesktop Documents Download Game Music Pictures Public Templates Videosllylocalhost $ (2)把Cartoon子目录建立在当前目录的Movie子目录下,且当前Movie子目录不存在。若用一条命令完成可进行如下操作:llylocalhost $ lsDesktop Documents Download Game Music Pictures Public Templates Videosllylocalhost $ mkdir -p Movie/Cartoonllylocalhost $ lsDesktop Download Movie Pictures TemplatesDocuments Game Music Public Videosllylocalhost $ ls MovieCartoonllylocalhost $ 5. 删除目录命令名称:rmdir - remove empty directories命令格式:rmdir OPTION. DIRECTORY.功能说明:删除空的目录。命令参数:-p 是当子目录被删除后使它也成为空目录的话,则顺便一并删除。 范例:(1)删除之前建立的Game的子目录。llylocalhost $ lsDesktop Download Movie Pictures TemplatesDocuments Game Music Public Videosllylocalhost $ rmdir Gamellylocalhost $ lsDesktop Documents Download Movie Music Pictures Public Templates Videosllylocalhost $(2)删除之前建立的Cartoon子目录。llylocalhost $ ls Desktop Documents Download Movie Music Pictures Public Templates Videosllylocalhost $ ls Movie/Cartoonllylocalhost $ rmdir -p Movie/Cartoon/llylocalhost $ lsDesktop Documents Download Music Pictures Public Templates Videosllylocalhost $6复制文件命令名称:cp - copy files and directories命令格式:cp OPTION. -T SOURCE DESTcp OPTION. SOURCE. DIRECTORYcp OPTION. -t DIRECTORY SOURCE.功能说明:复制文件。命令参数: -a 尽可能将档案状态、权限等资料都照原状予以复制。 -r 若 source 中含有目录名,则将目录下之档案亦皆依序拷贝至目的地。 -f 若目的地已经有相同档名的档案存在,则在复制前先予以删除再行复制。 范例:复制/etc/passwd文件到当前目录下,同时更名为mypasswd。llylocalhost $ cp /etc/passwd /mypasswdllylocalhost $ lsDesktop Download mypasswd Public VideosDocuments Music Pictures Templatesllylocalhost $ 7显示文件显示文件的命令可以用cat、more。下面分别介绍。(1)cat命令名称:cat - concatenate files and print on the standard output命令格式:cat OPTION FILE.功能说明:显示文件内容。命令参数:-n 或 -number 由 1 开始对所有输出的行数编号 -b 或 -number-nonblank 和 -n 相似,只不过对于空白行不编号 -s 或 -squeeze-blank 当遇到有连续两行以上的空白行,就代换为一行的空白行 -v 或 -show-nonprinting 范例:显示之前复制得来的passwd文件内容。llylocalhost $ cat mypasswd(2)more命令名称:more - file perusal filter for crt viewing命令格式:more -dlfpcsu -num +/ pattern + linenum file .功能说明:类似cat ,不过会以一页一页的显示方便使用者逐页阅读,而最基本的指令就是按空白键(space)就往下一页显示,按 b 键就会往回(back)一页显示,而且还有搜寻字串的功能(与 vi 相似),使用中的说明文件,请按 h 。 命令参数:-num 一次显示的行数 -d 提示使用者,在画面下方显示 Press space to continue, q to quit. ,如果使用者按错键,则会显示 Press h for instructions. 而不是 哔 声 -l 取消遇见特殊字元 L(送纸字元)时会暂停的功能 -f 计算行数时,以实际上的行数,而非自动换行过后的行数(有些单行字数太长的会被扩展为两行或两行以上) -p 不以卷动的方式显示每一页,而是先清除萤幕后再显示内容 -c 跟 -p 相似,不同的是先显示内容再清除其他旧资料 -s 当遇到有连续两行以上的空白行,就代换为一行的空白行 -u 不显示下引号 (根据环境变数 TERM 指定的 terminal 而有所不同) +/ 在每个档案显示前搜寻该字串(pattern),然后从该字串之后开始显示 +num 从第 num 行开始显示 fileNames 欲显示内容的档案,可为复数个数范例:分屏显示之前复制得来的passwd文件内容。llylocalhost $ more mypasswd8删除文件命令名称:rm - remove files or directories命令格式:rm OPTION. FILE.功能说明:删除空的目录。命令参数:-i 删除前逐一询问确认。 -f 即使原档案属性设为唯读,亦直接删除,无需逐一确认。 -r 将目录及以下之档案亦逐一删除。 范例:删除mypasswd文件llylocalhost $ rm mypasswd二、vi编辑器的使用vi或vim是Linux最基本的文本编辑工具,vi或vim虽然没有图形界面编辑器那样点鼠标的简单操作,但vi编辑器在系统管理、服务器管理中,永远不是图形界面的编辑器能比的。当没有安装X-windows桌面环境或桌面环境崩溃时,我们仍需要字符模式下的编辑器vi,vi或vim 编辑器在创建和编辑简单文档是最高效的工具。1 vi编辑器的三种工作模式 vi有三种工作模式:命令模式、插入模式和末行模式 命令模式在shell环境中启动vi时,初始就是进入命令模式。在该模式下,用户可以输入命令,用于管理自己的文档,包括控制屏幕光标的移动,字符、字或行的删除、移动、复制等。此时从键盘输入的任何字符都作为编辑命令来解释。若输入的是合法的vi命令,则vi在接受用户命令之后完成相应的动作;若输入的是不合法的命令,vi会响铃报警。需要注意的是,所输入的命令在屏幕上不显示。不管用户处于何种模式,只要用户按一下键,即可使vi进入命令模式。 插入模式只有在插入模式下才可以进行文字输入。在命令模式下输入命令i、附加命令啊、打开命令o、修改命令c、取代命令r或替换命令s都可以进入插入模式。在该模式下,用户输入的任何字符都被vi当做文件内容保存起来,并将其显示在屏幕上。在文本输入过程中,若想回到命令模式,按键即可。 末行模式在命令模式下,用户按键即可进入末行模式,此时vi会在显示窗口的最后一行显示一个“:”作为末行模
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 初三质量分析会班主任发言
- 电话销售礼仪培训
- 时政播报课件
- 2025版锅炉改造工程设计与施工合同
- 二零二五年瓷砖产品进出口贸易合同
- 2025版电商数据分析与营销托管合同范本
- 二零二五版家庭心理咨询与辅导服务合同书
- 2025版股权投资与资产管理合作协议书
- 二零二五版跨境贸易实务:磋商与订立合同操作指南及案例解析
- 2025版智能家电研发与市场推广合作合同
- 过程稽核培训
- 电子显微学解析钙钛矿型功能氧化物界面:结构、缺陷与性能关联
- 走流水款协议书
- 2025景观园林设计合同
- 城管协管笔试题及答案
- 种植土外购合同协议
- 带状疱疹后遗神经痛护理课件
- 2025-2030中国异噻唑啉酮中间体行业市场发展趋势与前景展望战略研究报告
- 2025-2030年中国异噻唑啉酮衍生物项目投资可行性研究分析报告
- 乡村青年新主播直播实训营招募
- ZYJ电液转辙机检修测试信号基础设备课件
评论
0/150
提交评论