xv6 homework shell


前言

避免做后即忘,故留档。


一、homework地址及内容

https://pdos.csail.mit.edu/6.828/2016/homework/xv6-shell.html
通过系统调用接口,实现一个简单的shell程序。shell也是一个进程shell框架代码,简单来说,就是我们补充上述框架代码,(并非在xv6系统中进行操作,也不是修改xv6-public里的代码),模拟实现Linux的shell程序,根据作业描述,我们只需要实现最简单的调用、重定向和管道操作即可。

二、我的操作流程

在Desktop新建一个6.828文件夹->新建hw文件夹->新建sh.c文件->将sh.c文件的代码复制过去->根据要求补充代码->gcc sh.c编译->./a.out执行测试->根据要求写t.sh并测试。

三、xv6的shell实现过程

1.shell 执行 getcmd 获得用户输入的命令
2.shell 执行 fork 创建一个shell进程的copy,然后shell进入wait状态
3.shell 执行 runcmd 运行用户的命令
4.runcmd函数调用exec系统调用加载适当的函数如:echo
5.在函数(echo) 的结束,有exit系统调用返回shell,shell从wait中退出
感谢

四、命令分析

1.执行命令 符号: “ ” //调用execv()函数。
2.重定向命令 > 或者 < //将输入或输出目标重新定位
3.列表命令,也就是多个命令 符号是分号 ;
4.管道命令,需要先建立管道 符号是 | //前一个命令的输出作为下一个命令的输入

我们需要实现的只有1,2,4。
对于1,我们只需要调用execv()函数,执行Linux已经给我们准备好的命令程序即可。注意可能有三种path格式。"ls" "/bin/ls" "/usr/bin/ls"
对于2,我们需要先将标准输入/输出关掉,在这里我们关掉rcmd->fd即可,再打开我们自己的文件即可以实现重定向。打开文件时将最小的fd赋给我们的文件。具体可查看这篇博客
对于4,我们需要了解进程间通信的内容。
在这里插入图片描述原博主
简单来说类似递归,现在大部分博主都是通过一个父进程fork出两个子进程实现,但是我那么写发现实现不了,至今未搞懂原因,所以我又查了一些资料,发现fork出一个子进程也可以实现。由父进程执行right,子进程执行left,left的输出作为父进程right的输入。如此即可实现一个管道命令,遇到下一个管道命依旧如此操作。
以上是主要思路,下面是对dup()等函数的理解,因为我们要把前一个命令的输出作为下一个命令的输入,所以肯定会遇到重定向的问题,虽然不会用到> < 命令,但是也要将stdin和stdout重新定向,子进程关闭写端,父进程关闭读端,因为管道只能是单向的,所以要这样做。dup()函数会复制fd表,至于为什么要复制,我也没搞太懂,总之我们要做的就是在相应进程中关闭相应的端口,再dup()复制留档现在有的端口,再把多余的端口全部关掉,然后递归调用runcmd()函数即可。

五、sh.c代码总览及重要函数

void runcmd(struct cmd *cmd)
int getcmd(char* buffer, int nbuf) // 检测输入是否是标准输入流stdin,然后把用户输入存到buffer里
struct cmd* execcmd() // 为一个cmd数据结构分配内存
struct cmd* redircmd(struct cmd *subcmd, char *file, int type)
struct cmd* pipecmd(st
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值