上节minishell当中,已经初步实现了一个简单命令的解析,这节来继续对更加复杂命令进行解析,包含:输入重定向的解析、管道行的解析、输出重定向的解析以及是否有后台作业的解析,如下:
下面对其进行实现,上节中实现了对单条命令的解析,如下:
这节因为是多条,所以解析命令的实现也得重新开始写,在写之前,先列一个实现步骤:
先写一个流程伪代码,交其框架定出来,然后再去实现一个个功能函数,最后整个功能完成,这是一个比较好的编码习惯,先全局,先局部:
下面先定义未实现的函数:
然后再定义用到的全局变量:
并且在extends.h文件中进行声明:
这时,先来make一下,看这些修改能否正常编译:
从中来看,目前这个简单命令的解析框架已经搭建完毕,接下来,则是一个个函数进行实现:
void get_command(int i):获取第几条命令:
在实现解析方法之前,需要重新定义一下我们的命令数据结构,因为这一次是由多个命令组成,而不是单个命令,那要定义成一个什么样的结构呢?
所以,我们的命令数据结构需调整为:
由于现在是多条命令解析,所以cmd需要将其声明为数组:
另外,对于是cmd的初始化操作也得进行变化:
在继续编写前,咱们先来编译一下,看是否能编译过,一步一步脚印,步步为营,这样编写能减少出错的机率:
出错了,这也说明好的编码习惯,得改一点,立马来确认是否能过编译通过,一点点往上加功能,这样也会比较踏实,好了解决错误,是由于在execute_command还是执行的单条命令,所以肯定会出错,先将其注释掉:
再来编译这次就ok了,下面开始进行解析,根据解析的示例图,需要将cmdline中的命令参数提取到avline数组中,所以声明两个变量来分别指向cmdline和avline:
下面开始一步步进行解析:
也就是这一步:
其实,这个解析还是有点问题,比如命令"cat < test.txt",依照上面编写的代码来分析,当解析完cat之后,因为遇到了' ',所以j++:
再次循环:
也就是cmd[i].args[1] = ' ';而实际上只有一个cat命令,并没有第二个参数,所以需要做如下处理:
/* * 解析简单命令至cmd[i] * 提取cmdline中的命令参数到avline数组中 * 并且将COMMAND结构中的args[]中的每个指针指向这些字符串 */ void get_command(int i){ /* cat < test.txt | grep -n public > test2.txt & */ int j = 0;//代表命令中的参数个数 int inword;//是否在单词中 while(*lineptr != '