首页UC › 练习:实现简单的Shell –实现源码

练习:实现简单的Shell –实现源码

这是《linux c编程一站式学习》中的一道练习题
用讲过的各种C 函数实现一个简单的交互式Shell,要求:
1 、给出提示符,让用户输入一行命令,识别程序名和参数并调用适当的exec函数执行程序,待执
行完成后再次给出提示符。
2 、识别和处理以下符号:
简单的标准输入输出重定向(< 和> ):仿照例 30.5 “wrapper” ,先dup2然后exec。
管道(| ):Shell进程先调用pipe创建一对管道描述符,然后fork出两个子进程,一个子进程
关闭读端,调用dup2把写端赋给标准输出,另一个子进程关闭写端,调用dup2把读端赋给标
准输入,两个子进程分别调用exec执行程序,而Shell进程把管道的两端都关闭,调用wait等
待两个子进程终止。
你的程序应该可以处理以下命令:
○ls△-l △-R○>○file1○
○cat○○file1○
○ 表示零个或多个空格,△表示一个或多个空格

下面是我的思路:
1:先对一条命令进行分析,看它有哪些管道(有那些程序需要执行),有哪些重定向,
2:然后打开重定向文件,再最后实现管道,执行程序
3:如果有多个程序需要执行,重复第二部

对于一条命令如:cat < file1|wc -c > file1
管道“|”将其分为两部分,cat < file1和wc -c > file1,所以首先根据“|”用把它分成两部分(split1()函数实现这一功能),再分别调用split2()函数根据重定向符探测各自的重定向文件,且前一部分的标准输出是后一部分的标准输入(这是管道的实现,我把它放到第3步再实现)。
在split2里,处理完“< file1”这种符号后,我把“< file1”替换成“ ”,也就是空格,这样一来,就方便根据空格来判别参数了,比如“wc -c > file1”的参数是“wc”和“-c”。

我用:
struct {
char* cmd;//用以记录用户输入的命令
char* prog;//需要执行的程序名
char* arg[10];//参数,最多10个
char infile[32];//最长32,用以记录重定向文件
char outfile[32];
}info[10];
来记录需要执行的程序名(最多10个),以及参数、重定向文件。
还用了int myfd[9][2]记录管道。

管道的实现:
假如已经执行了两次循环,已经运行了info[0].prog、info[1].prog。正准备执行info[2].prog,
此时info[1].prog和info[2].prog之间已经有管道了(上一个循环)。管道的两个文件描述符保存在myfd[1][0]和myfd[1][1]中。
检测测info[3].prog是否为空,否的话则新建一个管道myfd[2],用于info[2].prog和info[3].prog之间。

发表评论