2016-12-24 70 views
3

我寫了這個代碼來管2個命令:Ç - Linux的管道3個命令不起作用

// ls -l | tail -n 2 

int pfd[2]; 
pid_t pid; 
char *cmd1[] = {"ls", "-l", 0}; 
char *cmd2[] = {"tail", "-n", "2", 0}; 

pipe(pfd); 

pid = fork(); 
if (pid == 0) // child 
{ 
    dup2(pfd[1], STDOUT_FILENO); 
    close(pfd[0]); /* the child does not need this end of the pipe */ 

    execvp(cmd1[0], cmd1); 
    _exit(0); 
} 
else // parent 
{ 
    dup2(pfd[0], STDIN_FILENO); 
    close(pfd[1]); /* the child does not need this end of the pipe */ 

    execvp(cmd2[0], cmd2); 
} 

此代碼工作正常。現在

我想管3級的命令和我寫了這個代碼:

// ls -l | tail -n 2 | head -n 1 

int pfd1[2]; 
int pfd2[2]; 
pid_t pid1, pid2; 
char *cmd1[] = {"ls", "-l", 0}; 
char *cmd2[] = {"tail", "-n", "2", 0}; 
char *cmd3[] = {"head", "-n", "1", 0}; 

pipe(pfd1); 

pid1 = fork(); 

if (pid1 == 0) // child 1 
{ 
    dup2(pfd1[1], STDOUT_FILENO); 
    close(pfd1[0]); /* the child does not need this end of the pipe */ 

    execvp(cmd1[0], cmd1); 
    _exit(0); 
} 
else // parent 
{ 
    pipe(pfd2); 

    pid2 = fork(); 

    if (pid2 == 0) // child 2 
    { 
     dup2(pfd1[0], STDIN_FILENO); 
     close(pfd1[1]); /* the child does not need this end of the pipe */ 

     dup2(pfd2[1], STDOUT_FILENO); 
     close(pfd2[0]); /* the child does not need this end of the pipe */ 

     execvp(cmd2[0], cmd2); 
     _exit(0); 
    } 
    else // parent 
    { 
     dup2(pfd2[0], STDIN_FILENO); 
     close(pfd2[1]); /* the child does not need this end of the pipe */ 

     execvp(cmd3[0], cmd3); 
    } 
} 

此代碼編譯,但它只是需要從控制檯輸入永遠。
我做錯了什麼,我該如何解決?

+1

如果你想在原來的進程繼續(你通常會哪些),你需要'fork'一次每一個命令。每個命令之間需要一個管道。所以對於兩個命令(你的第一個例子),你需要兩個子進程(即兩個'fork'調用)和一個管道。對於第二個例子,您需要三次'fork'調用來創建三個子進程和兩個管道。 –

回答

0

請嘗試執行您的管道的示例。它使用相互遞歸,所以你不需要if ... else分支,你也可以使用這個例子,而不是隻有3個命令。

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 

typedef int Pipe[2]; 
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output); 

static void exec_nth_command(int ncmds, char ***cmds) { 
    if (ncmds > 1) { 
     pid_t pid; 
     Pipe input; 
     if (pipe(input) != 0) 
      exit(1); 
     if ((pid = fork()) < 0) 
      exit(1); 
     if (pid == 0) { 
      exec_pipe_command(ncmds - 1, cmds, input); /* Child */ 
     } 
     dup2(input[0], 0); 
     close(input[0]); 
     close(input[1]); 
    } 
    execvp(cmds[ncmds - 1][0], cmds[ncmds - 1]); 
} 

static void exec_pipe_command(int ncmds, char ***cmds, Pipe output) { 
    dup2(output[1], 1); 
    close(output[0]); 
    close(output[1]); 
    exec_nth_command(ncmds, cmds); 
} 

char *cmd0[] = {"ls", "-l", 0}; 
char *cmd1[] = {"tail", "-n", "2", 0}; 
char *cmd2[] = {"head", "-n", "1", 0}; 

static char **cmds[] = {cmd0, cmd1, cmd2}; 
static int ncmds = sizeof(cmds)/sizeof(cmds[0]); 

int main(int argc, char **argv) { 
    exec_nth_command(ncmds, cmds); 
    return(0); 
} 

測試

./a.out 
-rwxrwxr-x 1 dac dac 9640 jun 25 2016 test_apr