编写linux shell

我正在学习Unix C并为练习做一些练习。 我目前正在编写我自己的shell,其工作方式类似于linux bash shell。

我下面的代码提供了一个相当基本的shell。 它现在提供I / Oredirect。 我正在尝试添加对pipe道的支持。 最初,我只想添加对单个pipe道的支持。

我试图通过一些在线教程,但不能完全弄清楚从哪里开始。

目前,下面的shell可以处理下面的命令命令。 ls> abc,cat <file1> file2等

#include <stdlib.h> #include <unistd.h> #include <stdio.h> #include <sys/types.h> #include <string.h> #include <sys/wait.h> #include <fcntl.h> #define TRUE 1 int main(void) { char *arg_list[10]; int status; int counter = 0; int counter2 = 0; pid_t pid; char buf[100]; char inFile[10]; char outFile[10]; int fdIn, fdOut; while(TRUE) { printf("> "); if (!fgets(buf, 100, stdin)) return 0; pid = fork(); switch(pid) { case -1: return 1; case 0: { arg_list[counter] = strtok(buf, " \n"); counter = 0; while(arg_list[counter] != NULL) { counter++; arg_list[counter] = strtok(NULL, " \n"); } counter2 = 0; while(arg_list[counter2] != NULL) { if(!strcmp(arg_list[counter2], "<")) { if(arg_list[counter2+1] != NULL) { fdIn = open(arg_list[counter2+1], O_RDONLY); dup2(fdIn, STDIN_FILENO); } else { printf("No input file specified"); } arg_list[counter2] = 0; } else if(!strcmp(arg_list[counter2], ">")) { if(arg_list[counter2+1] != NULL) { fdOut = open(arg_list[counter2+1], O_CREAT | O_WRONLY | O_TRUNC, 0666); dup2(fdOut, STDOUT_FILENO); } else { printf("No output file specified"); } arg_list[counter2] = 0; } counter2++; } execvp(arg_list[0], arg_list); break; } default: waitpid(-1, &status, 0); break; } } return 0; } 

如果有人能指出我正确的方向,那将不胜感激。

Solutions Collecting From Web of "编写linux shell"

使用dup2() (成功)后,您将有两个文件描述符为一个文件打开。 您需要关闭原始文件描述符; 执行的进程不应该打开额外的文件描述符。

在使用dup2()之前,您还需要以适当的方式打开这些文件。 除此之外,这意味着strtok()不是一个好的选择,因为它指出了分隔符,但是你需要知道打开哪个文件来读取,哪些文件要写入)。

你也将需要放弃参数列表; 它应该只包含命令名和一个空指针,而不是两个文件名。

为什么你需要检查命令的类型? Unix shell不会专门处理任何命令; 所有的重定向,包括管道,都以相同的方式处理。 有一点需要注意的是重定向可以发生在任何地方 ,所以你应该首先解析出来; 尝试

 >foo ls <bar -la 

在某个时候 (管道是一个明显的例外,因为他们也分隔命令;语法|是一样的,虽然语义上有重定向涉及到加法。