Unix实验报告
实验: |
实验3 简单shell的设计和实现 |
专业: |
计算机科学与技术 |
班级: |
1班 |
姓名: |
姚怀聿 |
学号: |
22920202204632 |
2022年11月5日
目 录
实验内容描述
实验目的:
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整体进行处理,将最后一个换行符修改为结束符’\0’。
然后调用函数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
标签:shell,函数,实现,argv,实验,简单,输入 From: https://www.cnblogs.com/i-rong/p/17259312.html