您的位置:首页 > 运维架构 > Shell

Mit6.828 HW2 Shell

2016-05-17 13:46 537 查看

HW2:shell

编写1个简单的sell,识别并执行命令,同时支持重定向和管道操作。

测试脚本(t.sh):

ls > y
cat < y | sort | uniq | wc > y1
cat y1
rm y1
ls |  sort | uniq | wc
rm y


主要代码处:

case ' ':    //普通命令
ecmd = (struct execcmd*)cmd;
if(ecmd->argv[0] == 0)
exit(0);
/*fprintf(stderr, "exec not implemented\n");*/
if(!access(ecmd->argv[0], F_OK))   //cmd exists in current directory or not
execv(ecmd->argv[0], ecmd->argv);
else{
strcpy(path, root);
strcat(path, ecmd->argv[0]);     //cmd exists in /bin  or not
if(!access(path, F_OK))
execv(path, ecmd->argv);
else
fprintf(stderr, "%s: Command not found.\n", ecmd->argv[0]);
}
break;

case '>':       //输入输出重定向
case '<':
rcmd = (struct redircmd*)cmd;
//fprintf(stderr, "redir not implemented\n");
close(rcmd->fd);    //close stdin or stdout
if(open(rcmd->file, rcmd->mode, 0777) < 0) {       //open file with fd 0(stdin) or 1(stdout)
fprintf(stderr, "open %s failed!\n", rcmd->file);
exit(0);
}
runcmd(rcmd->cmd);
break;
case '|':    //管道
pcmd = (struct pipecmd*)cmd;
//fprintf(stderr, "pipe not implemented\n");
if(pipe(p) < 0){
fprintf(stderr, "create pipe failed!\n");
exit(0);
}
if(fork1() == 0){          //left cmd close  stdout to redirect to pipe's input
close(1);
dup(p[1]);
close(p[0]);
close(p[1]);
runcmd(pcmd->left);
}
if(fork1() == 0){           //right cmd close stdin to redirect to pipie's output
close(0);
dup(p[0]);
close(p[0]);
close(p[1]);
runcmd(pcmd->right);
}
close(p[0]);
close(p[1]);
wait(&r);
wait(&r);
break;


主要思路:

1.普通命令:通过access函数判断当前目录是否存在该命令,如果不存在则到/bin目录下寻找。最后使用execv函数执行 命令。(附exec函数簇)

2.重定向命令:关闭重定向命令的文件描述符,然后使用open命令打开重定向文件,由于open命令会自动选择最小的文 件标识符0(标准输入)或者1(标准输出),实现重定向。

3.管道命令:在父进程中创建1个无名管道,再fork 2个子进程,关闭管道左边进程的标准输出,使用dup函数复制管道输 入标识符(使1代表管道输入),关闭管道输入输出标识符;关闭管道右边进程的标准输入,使用dup函数复制管道输处标 识符(使0代表管道输出),最后关闭父进程管道的输入输出标识符(防止干扰)。

附:shell.c
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: