实现步骤:

  1. 接管用户输出命令字符串,拆分命令及参数存储。(自行设计数据存储构造)
  2. 实现一般命令加载性能

3.实现输出、输入重定向的性能

4.实现管道

5.反对多重管道
这道题感觉本人能力还没齐全看懂,看了大佬的代码https://blog.csdn.net/xiaoan0...

#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <sys/wait.h>#include <fcntl.h> #define MAXLINE 4096#define MAXPIPE 16#define MAXARG 8 struct {     char *argv[MAXARG];    char *in, *out;} cmd[MAXPIPE+1]; int parse(char *buf, int cmdnum){    int n = 0;    char *p = buf;    cmd[cmdnum].in = cmd[cmdnum].out = NULL;     //ls -l -d -a -F  > out    while (*p != '\0') {         if (*p == ' ') {            //将字符串中所有的空格,替换成'\0',不便后续拆分字符串            *p++ = '\0';            continue;        }         if (*p == '<') {            *p = '\0';            while (*(++p) == ' ');    /* cat <     file 解决间断多个空格的状况*/            cmd[cmdnum].in = p;            if (*p++ == '\0')//输出重定向<前面没有文件名                return -1;            continue;        }         if (*p == '>') {            *p = '\0';            while (*(++p) == ' ');            cmd[cmdnum].out = p;            if (*p++ == '\0')                return -1;            continue;        }         if (*p != ' ' && ((p == buf) || *(p-1) == '\0')) {             if (n < MAXARG - 1) {                cmd[cmdnum].argv[n++] = p++;   //"ls -l -R > file"                continue;            } else {                return -1;            }        }        p++;    }     if (n == 0) {        return -1;    }     cmd[cmdnum].argv[n] = NULL;     return 0;} int main(void){    char buf[MAXLINE];    pid_t pid;    int fd, i, j, pfd[MAXPIPE][2], pipe_num, cmd_num;    char* curcmd, *nextcmd;     while (1) {        printf("mysh%% ");        if (!fgets(buf, MAXLINE, stdin))            exit(0);        // "ls -l\n"        if (buf[strlen(buf)-1]=='\n')            buf[strlen(buf)-1]='\0';        cmd_num = 0;        nextcmd = buf;         while ((curcmd = strsep(&nextcmd, "|"))) {             if (parse(curcmd, cmd_num++)<0) {                cmd_num--;                break;            }             if (cmd_num == MAXPIPE + 1)                     break;        }         if (!cmd_num)            continue;         pipe_num = cmd_num - 1;     //依据命令数确定要创立的管道数目         for (i = 0; i < pipe_num; i++) {    //创立管道            if (pipe(pfd[i])) {                perror("pipe");                exit(1);            }        }         for (i = 0; i < cmd_num; i++) {     //管道数目决定创立子过程个数            if ((pid = fork()) == 0)                break;        }         if (pid == 0) {            if (pipe_num) {     //用户输出的命令中含有管道                  if (i == 0) {                //第一个创立的子过程                    dup2(pfd[0][1], STDOUT_FILENO);                    close(pfd[0][0]);                     for (j = 1; j < pipe_num; j++) { //在该子过程执行期间,敞开该过程应用不到的其余管道的读端和写端                        close(pfd[j][0]);                        close(pfd[j][1]);                    }                 } else if (i==pipe_num) {    //最初一个创立的子过程                    dup2(pfd[i-1][0], STDIN_FILENO);                    close(pfd[i-1][1]);                     for (j = 0; j < pipe_num-1; j++) { //在该子过程执行期间,敞开该过程不应用的其余管道的读/写端                        close(pfd[j][0]);                        close(pfd[j][1]);                    }                 } else {                    dup2(pfd[i-1][0], STDIN_FILENO);    //重定两头过程的规范输出至管道读端                    close(pfd[i-1][1]);                 //close管道写端                     dup2(pfd[i][1], STDOUT_FILENO);     //重定两头过程的规范输入至管道写端                    close(pfd[i][0]);                   //close管道读端                     for (j = 0; j < pipe_num; j++)    //敞开不应用的管道读写两端                        if (j != i || j != i-1) {                            close(pfd[j][0]);                            close(pfd[j][1]);                        }                }            }            if (cmd[i].in) {            /*用户在命令中应用了输出重定向*/                fd = open(cmd[i].in, O_RDONLY); //关上用户指定的重定向文件,只读即可                if (fd != -1)                    dup2(fd, STDIN_FILENO);     //将规范输出重定向给该文件            }            if (cmd[i].out) {           /*用户在命令中应用了输入重定向*/                fd = open(cmd[i].out, O_WRONLY|O_CREAT|O_TRUNC, 0644);  //应用写权限关上用户指定的重定向文件                if (fd != -1)                    dup2(fd, STDOUT_FILENO);    //将规范输入重定向给该文件            }             execvp(cmd[i].argv[0], cmd[i].argv);    //执行用户输出的命令            fprintf(stderr, "executing %s error.\n", cmd[i].argv[0]);            exit(127);        }         /*  parent */        for (i = 0; i < pipe_num; i++) { /*父过程不参加命令执行,敞开其把握的管道两端*/            close(pfd[i][0]);            close(pfd[i][1]);        }         for (i = 0; i < cmd_num; i++) { /*循环回首子过程*/            wait(NULL);        }    }}

第一个函数parse()是用来解决输出格局的,如空格多输出了,重定向符号><与文件之间的书写标准等问题,前面的临时还在思考!