2016-04-16 41 views
0

我正在编写一个简单的shell,我想改变我的程序以添加多个管道命令的可能性,如“echo foo | cat | cat | cat | cat | wc”。我写了两个命令,但对于多个我不能。在C中创建多个管道

这里是我的程序的源代码:

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 
} 

预先感谢您的帮助。

+0

你想如何运行这个程序?它是否像'./myprog cmd1 | cmd2 | cmd3'等等? –

+0

@ NTN不喜欢./myprog和放后命令像bash – Yoan15

+0

“多个我不能”是不是一个适当的问题陈述。另外,在过去的几周里,关于可能参加同一个大学课程的人编写一个shell的问题有好几十个,也许你应该使用搜索功能。 –

回答

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()创建一个管道,并创建一个子进程来执行给定的命令,从给定输入流以输入和输出发送到它返回到父流中。

+0

谢谢你的帮助。但是,你的函数中的“int create_pipe”是什么意思?我不知道它在哪里宣布。 – Yoan15

+0

@ Yoan15这是'create_sub_process()'的第三个参数。 – jdarthenay

+0

您的解决方案很有趣,但如何使其与我的程序相适应?这是我真正的问题:( – Yoan15