c - Linux管道3命令不起作用

时间:2016-12-24 19:19:36

标签: c linux pipe

我已将此代码写入管道2命令:

// 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 个答案:

答案 0 :(得分: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