HW2 shell

HW2 Shell

6.828的shell主要有两个功能,一个是解析shell命令,一个是执行它们。6.828可以识别普通命令,重定向和pipe管道等。

1.普通exec命令的实现

在case’ '中直接实现即可,根据提示用到了unistd.h头文件中的execv方法
在这里插入图片描述
根据man 3 exec显示的提示可以看到:execv的第一个参数是路径,第二个参数是一个数组。根据详细描述可以知道,execv的第一个参数是和文件路径相联系的,所以我们可以简单地写出应用逻辑如下:
在这里插入图片描述

 //exec
  case ' ':
    ecmd = (struct execcmd*)cmd;
    if(ecmd->argv[0] == 0)
      _exit(0);
    //fprintf(stderr, "exec not implemented\n");
    // Your code here ...
    execv(ecmd->argv[0], ecmd->argv);
    break;

但这样写出的代码只能在/bin目录下运行,
在这里插入图片描述
要使ls能够直接成功运行,需要借助另外的几个函数。

/ pathname :文件路径
// mode : 操作模式
int access(const char * pathname, int mode)

R_OK      测试读许可权
W_OK      测试写许可权
X_OK      测试执行许可权
F_OK      测试文件是否存在

access函数用来测试文件是否存在,strcpy函数用来复制字符串,strcat函数用来连接字符串。
当我们输入/bin/ls时,ecmd->argv[0]的值为/bin/ls,而此时我们要做的是当输入ls时,execv的第一个参数仍然为/bin/ls此时就要用到strcat函数,将/bin/与ls连接起来。代码如下;
在这里插入图片描述执行结果如下图:
在这里插入图片描述

2.重定向的实现

实现重定向主要用到了open函数,该函数的定义如下:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);

open函数的返回值如果操作成功,它将返回一个文件描述符,如果操作失败,它将返回-1。

参数简介:见博客https://blog.csdn.net/ArchyLi/article/details/78937937。
Linux访问模式,十进制表示:

-rw------- (600)    只有拥有者有读写权限。
-rw-r--r-- (644)    只有拥有者有读写权限;而属组用户和其他用户只有读权限。
-rwx------ (700)    只有拥有者有读、写、执行权限。
-rwxr-xr-x (755)    拥有者有读、写、执行权限;而属组用户和其他用户只有读、执行权限。
-rwx--x--x (711)    拥有者有读、写、执行权限;而属组用户和其他用户只有执行权限。
-rw-rw-rw- (666)    所有用户都有文件读、写权限。
-rwxrwxrwx (777)    所有用户都有读、写、执行权限。

此处采用0600(可读可写)的访问模式,所以代码如下:

case '>':
  case '<':
    rcmd = (struct redircmd*)cmd;
    //fprintf(stderr, "redir not implemented\n");
    // Your code here ...
    //close current startdard input/output
    close(rcmd->fd);
    //open the target file,and give the startdard input/output to it
    if(open(rcmd->file,rcmd->flags,0600)<0){
       fprintf(stderr, "fail to open the file %s\n",rcmd->file);
       exit(0);
    }
    //else exec the command
    runcmd(rcmd->cmd);
    break;

代码解释:因为每次分配文件描述符时都从最小的开始分配,因此关闭当前文件描述符后(标准输入/输出描述符),会将该关闭的描述符自动分配给当前打开的文件。执行结果如下;
在这里插入图片描述可见,成功实现了重定向。

pipe管道的实现

什么是管道,见以下博文:https://www.jianshu.com/p/9c0c2b57cb73。该文章将什么是管道,已阐述得十分清楚。

实现需要用到dup方法,该方法的使用说明见博客:https://blog.csdn.net/silent123go/article/details/71108501。

实现需要用到fork方法,见博客:https://blog.csdn.net/weixin_30338481/article/details/97933030?utm_medium=distribute.pc_relevant.none-task-blog-title-2&spm=1001.2101.3001.4242。

故最后的实现为:

 case '|':
    pcmd = (struct pipecmd*)cmd;
    //fprintf(stderr, "pipe not implemented\n");
    // Your code here ...
    //create a pipe
    if(pipe(p)<0){
      fprintf(stderr, "cannot create pipes\n");
      exit(0);
    }
    //child proccess,read
    if(fork1()==0){
       //close read
       close(0);
       //child read point to pipe read
       dup(p[0]);
       //close pipe read and pipe write
       close(p[0]);
       close(p[1]);
       runcmd(pcmd->right);
    }
    //parent process,write
    else{
       //close write
       close(1);
       //parent write point to pipe write
       dup(p[1]);
       //close pipe read and pipe write
       close(p[0]);
       close(p[1]);
       runcmd(pcmd->left);
    }
    break;

执行结果:
在这里插入图片描述注意必须在/usr/bin目录下执行该语句,不然找不到方法。显示的三个数字分别表示:行,字和总字母数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值