2013-07-13 52 views
5

我正在尝试在C中实现一个多层管道的外壳。C编码多个管道

我只有一个管道功能, b但不是| b | C。

int c[2]; 
int returnv; 
pid_t id; 

pipe(c); 
pid = fork()) == 0 
if (pid) 
{ 
    dup2(c[1], 0); 
    close(p[1]); 
    close(p[1]); 
    execvp(array(0), array); 
} 

if ((pid = fork()) == 0) 
{ 
    dup2(p[0], 1); 
    close(p(0)); 
    close(p[0]); 
    returnv = execvp(array[0], array); 
} 

close(p[1]); 
wait(NULL); 
wait(NULL); 
wait(NULL); 
return returnv; 

这是第二个版本:

int i = 0; 

while (i < x) 

{ 
pipe(c); 
if ((pid = fork()) == 0) 
{ 
    dup2(t[i], 1); 
    if (i < 2) 
     dup2(p[0], 1); 
    close(p[1]); 
r= execvp(cmd[i][0], cmd[i]); 
} 
    wait(NULL); 
    close(p[0]); 
    i += 1; 
    t[i] = p[1]; 

我如何添加这个小东西,这将使该代码管理多个管好吗? 非常感谢!

+0

其实你只需要调用fork()两次,而你只需要一次。这是因为fork()返回两次:子进程为0,父进程为> 1(通常是子进程的pid)。 我不认为你需要所有的代码来做你需要的。 – none

+0

我已经花了这么多时间在这一个,这是唯一的作品^^我想只有一个调用execvp所需的多管道,但我不能让它的工作。 :( – user2145240

+0

不要从帖子中删除代码,它使答案无效 – FDinoff

回答

8

编辑:根据您的评论

要执行你需要存储你的所有命令的地方倍数管道。 这就是为什么我使用结构选项卡。

检查这个新版本,也许更容易理解

所以首先你需要一个标签或东西来存储你的所有命令:

int main() 
{ 
    char *ls[] = {"ls", NULL}; 
    char *grep[] = {"grep", "pipe", NULL}; 
    char *wc[] = {"wc", NULL}; 
    char **cmd[] = {ls, grep, wc, NULL}; 

    loop_pipe(cmd); 
    return (0); 
} 

谁就会通过Tab运行并启动一切

功能
void loop_pipe(char ***cmd) 
{ 
    int p[2]; 
    pid_t pid; 
    int fd_in = 0; 

    while (*cmd != NULL) 
    { 
     pipe(p); 
     if ((pid = fork()) == -1) 
     { 
      exit(EXIT_FAILURE); 
     } 
     else if (pid == 0) 
     { 
      dup2(fd_in, 0); //change the input according to the old one 
      if (*(cmd + 1) != NULL) 
      dup2(p[1], 1); 
      close(p[0]); 
      execvp((*cmd)[0], *cmd); 
      exit(EXIT_FAILURE); 
     } 
     else 
     { 
      wait(NULL); 
      close(p[1]); 
      fd_in = p[0]; //save the input for the next command 
      cmd++; 
     } 
    } 
} 
+2

@ user2145240我改变了我的答案,旧的有点混乱,因为我用它来做很多其他的事情;) – Alexis

+1

@ user2145240你能告诉我你是怎么做的因为我在我的电脑上工作得很好,而且在ideone上工作也很好http://ideone.com/80e3nd – Alexis

+1

@ user2145240很少有事情要检查:printf(“9 - On rentre ici?”);请不要忘记\ n在最后, 在exec下添加一个perror,以确保你没有在env – Alexis

0

我将给出两种管道模型的工作版本和三种管道模型的提示。试试看看它是否有效。注意:如果你没有包含正确的头文件,dup2()将是一场噩梦。

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

int p[2]; 
int pid; 
int r; 

main() 
{ 
    char *ls_args[] = {"ls", NULL}; 
    char *grep_args[] = {"grep", "pipe", NULL}; 

    pipe(p); 

    pid = fork(); 
    if (pid != 0) { 
      // Parent: Output is to child via pipe[1] 

      // Change stdout to pipe[1] 
      dup2(p[1], 1); 
      close(p[0]); 

      r = execvp("ls", ls_args); 
    } else { 
      // Child: Input is from pipe[0] and output is via stdout. 
      dup2(p[0], 0); 
      close(p[1]); 

      r = execvp("grep", grep_args); 
      close(p[0]); 
    } 

    return r; 
} 

对于| b | c,提示是使用两个管道,即p1 [2]和p2 [2]。试试这个,让我们知道它是如何工作的。