在C中创建多个管道

时间:2016-04-16 08:43:32

标签: c shell

我正在写一个简单的shell,我想改变我的程序,增加多个管道命令的可能性,如“echo foo | cat | cat | cat | cat | wc”。我已经为两个命令写了但是多个我不能。

以下是我的程序的源代码:

if (pid == 0) // in the child process 
 {  
   for (i = 0; i < command; i++)  // for each cmd
   {
     if (argv[i][0] == '|') 
     {
       j = i; 
     }
   }
   if (j > 0) 
   {
     if (pipe(p)) 
     {
       fprintf(stderr, "pipe");
       exit(1);
     }
     argv[j] = NULL;
     if (fork() == 0) // child
     { 
        j = -1;
        close(p[0]);
        dup2(p[1],1);
        close(p[1]);
     } 

     // parent 
     close(p[1]);  
     dup2(p[0], 0);
     close(p[0]);                              
   }
   for (i = 0; dirs[i] != 0; i++) 
   {
     snprintf(pathname, sizeof(pathname), "%s/%s", dirs[i], argv[j+1]);
     execv(pathname, &argv[j+1]);
   }
 }
 else 
 {  
   while (wait(0) != pid) // parent: wait child
 }

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我举了一个你想要做的例子。我使用常量作为命令,我将命令行解析给你。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>

static char *my_command0[] = {"cat", "stackoverflow.c", NULL};
static char *my_command1[] = {"grep", "return", NULL};
static char *my_command2[] = {"sed", "s/^ *//g", NULL};

static char **const my_commands[] = {
  my_command0,
  my_command1,
  my_command2,
  NULL
};

int create_sub_process(char *const command[], int input_stream)
{
    int pipefd[2] = {-1, -1};
    pid_t fk;

    if (pipe(pipefd) < 0)
    {
        perror("pipe");
        close(input_stream);
        return -1;
    }

    if ((fk = fork()) < 0)
    {
        perror("fork");
        close(pipefd[0]);
        close(pipefd[1]);
        close(input_stream);
        return -1;
    }

    if (fk == 0)
    {
        close(pipefd[0]);

        close(0);
        dup(input_stream);
        close(input_stream);

        close(1);
        dup(pipefd[1]);
        close(pipefd[1]);

        execvp(command[0], command);
        perror("execvp");
        exit(1);
    }

    close(input_stream);
    close(pipefd[1]);

    return pipefd[0];
}

int main()
{
    int fd = dup(0);

    for (int i = 0; my_commands[i] != NULL; i++)
    {
        fd = create_sub_process(my_commands[i], fd); // replace my_commands[i] by whatever you need to execute - check: man execvp
        if (fd < 0)
        {
            exit(1);
        }
    }

    // Also adapt the following lines to whatever you want to do with last child results
    close(0);
    dup(fd);
    close(fd);

    execlp("cat", "cat", (char *)NULL);
    perror("execlp");

    return 1;
}

create_sub_process()创建一个管道并创建一个子进程来执行给定的命令,从给定的输入流中获取输入并将输出发送到它返回到父级的流。