本文旨在对自己所写的myshell中的几个思路做以记录
多管道复合
整体的思路是每个管道符隔开的命令将由shell进程创建一个子进程去执行,那么每个管道符隔开的命令之间将会是一系列兄弟进程,因此问题就在于怎么把数据在兄弟进程之间传递,一开始打算使用高端的pipe()函数,但是过程中反复调试总有问题,可能是自己对进程的理解不够深入,最后的解决方案是使用两个临时文件,pipe_w负责写入管道前的命令的执行结果 ,管道后面的命令在开始执行之前先将pipe_w重命名成pipe_r并从中读取输入,这样如果该条命令的后面还有一条管道,则可以继续创建pipe_w并将执行结果写入其中.多组输入输出重定向组合
对于多组输入输出重定向的解决方案感觉有点丑陋,但这里还是做以记录,等到将来自己能够实现更好的做法之后再回来嘲笑自己,哈哈.
核心的思路就是,对于每个输入或输出重定向都单独的fork一个新的进程去执行,
例如:cat > 1 > 2 > 3
这个复合重定向,实际上我是将其拆分成cat > 1 cat > 2 cat > 3
这样分三次去递归执行,,,,是不是相当的丑陋……
复杂的命令解析
由于支持了复杂的管道以及输入输出重定向,因此对于用户(其实是组长哈哈哈),输入的复杂命令就不能一句 不支持的命令 就带过了,
而处理过程可以说是本程序的核心了,在这里我简单的说明一下命令最终的解析结果
/*
* 重定向记录结构体
*/
typedef struct{
char red_inp[10][256]; //某条命令的输入重定向列表
char type_inp[10]; //对于列表中的每一条重定向记录,标记一个类型 1 < 2<<(暂无)
char red_pri[10][256]; //输出重定向列表
char type_pri[10]; // 1 > 2>>
}redir_t;
/*
* 存储一条不含 | 的命令的参数
* 以及I/O重定向的目标(NULL表示标准I/O)
*/
typedef struct {
char *(argv[20]);
redir_t rec;
} cmd_t;
使用上述结构体将由复杂的多管道 多输入输出重定向的结果储存起来,然后在后续的程序中使用,而至于具体的解析以及使用过程,稍后会附上源代码链接,有言在先,为了用多个函数对输入命令进行分级解析,代码中多处使用二级指针在函数之间传递参数,导致程序可能阅读起来比较困难,有兴趣的同学可以看看鄙人晦涩难懂的代码.