首页 > 系统相关 >实验3 简单shell的设计和实现

实验3 简单shell的设计和实现

时间:2023-03-26 20:00:17浏览次数:42  
标签:shell 函数 实现 argv 实验 简单 输入

Unix实验报告

实验:

实验3 简单shell的设计和实现

专业

计算机科学与技术

班级

1班

姓名

姚怀聿

学号

22920202204632

2022年11月5日

目 录

一、 实验内容描述 2

二、 设计、实验构思 2

三、 实验结果 7

四、 实验心得与建议 9

五、 完成人姓名及完成时间 10

实验内容描述

实验目的:

1、练习使用编程环境,包括shell的命令,vi和gcc编译器。

2、体会进程概念,了解fork,execve,wait等系统调用。

实验要求实现允许输入命令带参数的简单shell。

实验具体要求如下:

  1. 除了系统调用execve,不允许使用其他的exec函数。输入应当允许带多个参数(一行内可以表示),不考虑通配符 (即“*”、“?”、“-”等等)的处理。
  2. 输入错误命令能提示出错并进入下一轮接收命令状态。
  3. 可以用Ctrl-C和Ctrl-\结束简单shell的运行。
  4. 程序运行正确,提示简洁明确。

设计、实验构思

  1. 正确理解并使用系统调用fork()和waitpid()

程序中利用fork()函数创建一个新的进程,即子进程,并在子进程中调用execve()函数,实现指令的执行。在父进程中,调用waitpid()函数,等待子进程终止后父进程执行,继续进行下一轮的指令输入和执行。

实现函数print_promt(),该函数用于打印输入提示字:

运行程序后,首先会打印出一行输入提示字,并显示当前工作路径,然后while循环输入,输入的内容存入字符数组buf中,调用函数read_from_buf(),将buf中的内容用空格分开,存入字符串数组argv中,并将命令和参数的个数保存在变量argc中,该函数在下面会具体介绍。之后调用fork()函数创建子进程,并在子进程中调用execve()函数执行命令。父进程中调用waitpid()等待子进程的状态更改。

init函数实现如下:

对全局变量argv和argc进行初始化

  1. 构造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。

  1. cd、pwd和输入输出重定向的实现

其实到这里,大部分简单shell的输入都已经可以实现了,但是该程序还不能实现如cd、pwd以及输入输出重定向的操作,于是,我附加实现了该功能。实现cd和pwd功能需要在fork之前实现,而不要在子进程中去实现,否则会有一些小bug(比如输入cd后必须要再按一次回车才能执行成功)。而实现输入输出重定向就需要用到我定义在全局的rf,wf以及dup2函数了。具体程序如下:

  1. cd和pwd的实现

  1. 输入输出重定向

该功能使用redirect()函数实现,具体如下:

至此,shell基本功能都可以实现了。

实验结果

源程序名

可执行程序名

shell.c

shell

编译生成可执行文件:

使用如下指令:

`make shell`,即可得到可执行文件`shell`

运行程序:

  1. 使用`./shell`运行程序:

观察到输入提示字显示正常。

  1. 输入`/bin/ls -l -a`:

观察到结果正确。

  1. 输入`/bin/gcc -g -c shell.c`

观察到结果正确。

  1. 输入`/usr/ls -l -a`

观察到结果正确,目录/usr/下没有ls程序。

  1. 输入`cd`

观察到结果正确。

  1. 输入`pwd`

观察到结果正确。

  1. 输入`/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

相关文章

  • Android简单集成高德地图API
    首先进入高德官网  高德开放平台|高德地图API(amap.com)  注册登录完成之后创建新应用  点击之后呈现如下页面:  Key的名称随便起,主要是提交后会有一个......
  • JS 做一个简单的 Parser
    前言前些天偶然看到以前写的一份代码,注意有一段尘封的代码,被我遗忘了。这段代码是一个简单的解析器,当时是为了解析日志而做的。最初解析日志时,我只是简单的正则加上分割,写......
  • 实验2 目录树的遍历
    Unix实验报告实验:实验2目录树的遍历专业:计算机科学与技术班级:1班姓名:姚怀聿学号:229202022046322022年10月21日目录一......
  • Vmware UEFI装Windows8 Image type X64 is not support by this IA32 shell
      挂载ISO后,跟着启动虚拟机,会见到显示"unsuccessfulEFInetwork"  输入bootiaX86.EFI;回车 "ImagetypeIA32isnotsupportedbythisX64shell"或者:......
  • PTA实验1~3分析及总结
    1.前言    自接触面向对象的程序设计这门课以来,已经完成了三次pta上的实验作业了,在这里对前面的练习做一些分析,同时也总结一些经验。    OK,首先,在难度......
  • AutoResetEvent/ManualResetEvent 的简单理解与运用
    AutoResetEvent和ManualResetEvent只是构造函数包装器它们唯一要做的就是使用EventResetMode.AutoReset或EventResetMode.ManualReset从EventWaitHandle调用构造函数.......
  • 03_数字证书实验
    《信息安全综合实践》实验报告数字证书一、实验目的了解密码技术的应用学习OpenSSL的相关命令及应用,了解数字证书的管理了解数字证书的应用二、实验内容序......
  • C# Autofac简单用法
    十年河东,十年河西,莫欺少年穷学无止境,精益求精新建一个控制台程序,如下 MyAutoFac项目引用NugetautofacV6.5版本新建如下接口:publicinterface动物{void......
  • 深入学习shell命令-grep
    grep命令格式mangrep对grep命令的说明如下:grep-printlinesmatchingapatterngrep[OPTIONS]PATTERN[FILE...]grep[OPTIONS][-ePATTERN|-fFILE][FIL......
  • 11.getshell常见思路与技巧
    getshell常见思路与技巧1、常规打点思路信息收集:绕开CDN找到所有靶标的真实IP找到所有目标真实的C段对所有的C段进行基础服务器的探测,端口的扫描、识别对所有目标的......