盈彩体育注册(中国)有限公司 | 您所在的位置:网站首页 › 盈彩体育注册(中国)有限公司 › 实验3 简单shell的设计和实现 |
目 录 一、 实验内容描述 2 二、 设计、实验构思 2 三、 实验结果 7 四、 实验心得与建议 9 五、 完成人姓名及完成时间 10 实验内容描述实验目的: 1、练习使用编程环境,包括shell的命令,vi和gcc编译器。 2、体会进程概念,了解fork,execve,wait等系统调用。 实验要求实现允许输入命令带参数的简单shell。 实验具体要求如下: 除了系统调用execve,不允许使用其他的exec函数。输入应当允许带多个参数(一行内可以表示),不考虑通配符 (即“*”、“?”、“-”等等)的处理。输入错误命令能提示出错并进入下一轮接收命令状态。可以用Ctrl-C和Ctrl-结束简单shell的运行。程序运行正确,提示简洁明确。设计、实验构思正确理解并使用系统调用fork()和waitpid()程序中利用fork()函数创建一个新的进程,即子进程,并在子进程中调用execve()函数,实现指令的执行。在父进程中,调用waitpid()函数,等待子进程终止后父进程执行,继续进行下一轮的指令输入和执行。 实现函数print_promt(),该函数用于打印输入提示字: 运行程序后,首先会打印出一行输入提示字,并显示当前工作路径,然后while循环输入,输入的内容存入字符数组buf中,调用函数read_from_buf(),将buf中的内容用空格分开,存入字符串数组argv中,并将命令和参数的个数保存在变量argc中,该函数在下面会具体介绍。之后调用fork()函数创建子进程,并在子进程中调用execve()函数执行命令。父进程中调用waitpid()等待子进程的状态更改。 init函数实现如下: 对全局变量argv和argc进行初始化 构造execve函数的参数在APUE第三版课本程序上进行修改,字符数组buf保存用户的输入,包括命令和参数。由于shell命令的命令名和各参数之间是用空格分隔开的,因此可以用空格作为分界符。通过一个循环可以把buf数组中的命令和各个参数依次分隔开,并将其中的每一项取出来赋给字符串数组argv,int类型的argc用于记录命令和参数的总个数,每次读取前需要先初始化,将argv数组清空,argc置零。注意argv数组的最后一个指针必须是NULL。接着就可以调用execve(argv[0], argv, environ)来执行用户输入的命令。 该功能用函数read_from_buf()实现,具体如下: type用于指示当前参数的类型,0表示常规,1表示读文件,2表示写文件。rf和wf均为全局变量。 首先对buf整体进行处理,将最后一个换行符修改为结束符’ ’。 然后调用函数strtok(),将buf用空格分开。分开后得到的每个参数放入argv中,并让argv的最后一个单元为NULL。 cd、pwd和输入输出重定向的实现其实到这里,大部分简单shell的输入都已经可以实现了,但是该程序还不能实现如cd、pwd以及输入输出重定向的操作,于是,我附加实现了该功能。实现cd和pwd功能需要在fork之前实现,而不要在子进程中去实现,否则会有一些小bug(比如输入cd后必须要再按一次回车才能执行成功)。而实现输入输出重定向就需要用到我定义在全局的rf,wf以及dup2函数了。具体程序如下: cd和pwd的实现输入输出重定向该功能使用redirect()函数实现,具体如下: 至此,shell基本功能都可以实现了。 实验结果源程序名 可执行程序名 shell.c shell 编译生成可执行文件: 使用如下指令: `make shell`,即可得到可执行文件`shell` 运行程序: 使用`./shell`运行程序:观察到输入提示字显示正常。 输入`/bin/ls -l -a`:观察到结果正确。 输入`/bin/gcc -g -c shell.c`观察到结果正确。 输入`/usr/ls -l -a`观察到结果正确,目录/usr/下没有ls程序。 输入`cd`观察到结果正确。 输入`pwd`观察到结果正确。 输入`/bin/cat shell.c > /tmp/out`使用diff命令查看两文件内容是否一致,无输出,说明两文件内容一致,结果正确。 实验心得与建议实验心得:本次实验实现的一个简单的myshell还是有很多的不足,虽然额外实现了cd、pwd这些简单的命令,但是还是不能支持真正shell的一些功能比如:tab补全、回溯到上一条指令等等。这让我体会到只是一个简单的shell黑窗口的开发难度也是不容小觑的,linux能发展到今天这种程度离不开前人的智慧和创造力,我们要站在巨人的肩膀上不断学习、勇攀高峰。 建议:希望老师能够提前发布下一次实验课的任务,这样可以让我们有时间对实验进行预习,使得实验的完成更加顺利。 完成人姓名及完成时间完成人姓名 完成时间 姚怀聿 2022年11月5日
完整代码链接:https://gitee.com/i-rong/huaiyuyao/tree/master/unix/homework |
CopyRight 2018-2019 盈彩体育注册(中国)有限公司 版权所有 豫ICP备16040606号-1 |