Piped输出重复

有人可以向我解释为什么我的输出在ls命令中有重复. ls -l |的正常运行sort不会给我一个重复的输出所以可能是什么问题?

基本上我正在尝试从一个命令管道输出并将其输入另一个命令.该程序到目前为止工作,但输出显示重复数据.加上并解释为什么我需要在dup2之后关闭它真的很有帮助:)

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


// function declarations
void executeLs(int data_pipe[]);
void executeSort(int data_pipe[]);

int main(){

        int data_pipe[2]; // array storing the file descriptors
        int childls_pid; // ls child process
        int childSort_pid; // sort child process
        int rc; // return vaue of the pipe
        int child_status1;
        int child_status2;

        rc = pipe(data_pipe);
        if(rc == -1){
            perror("pipe");
            exit(1);
        }


        childls_pid = fork();
        childSort_pid = fork();

        // Ls Child process
        switch(childls_pid) {
        case -1:
                perror("fork childLs Error");
                exit(1);
        case 0:
                // inside of child process
                executeLs(data_pipe);
                exit(0);
        default:
            break;
        }

        // Sort child process
        switch(childSort_pid) {
        case -1:
                perror("fork childSort Error");
                exit(1);
        case  0:
                executeSort(data_pipe);
                exit(0);
        default:
                wait(&child_status2);
        }
        return 0;
}
void executeLs(int data_pipe[]){

    // Closes the read file descriptor
    close(data_pipe[0]);

    dup2(data_pipe[1], STDOUT_FILENO);

    // confused as to why this is necessary
    close(data_pipe[1]);

    execlp("ls", "ls", "-1", NULL);
}
void executeSort(int data_pipe[]){

    // close the write file descriptor
    close(data_pipe[1]);

    dup2(data_pipe[0], STDIN_FILENO);
    close(data_pipe[0]);
    execlp("sort","sort", NULL);
}

最佳答案 原因是你要求比你想要的更多的流程.当你这样做时:

    childls_pid = fork();
    childSort_pid = fork();

你在原始父进程和第一个fork()创建的进程中执行第二个fork().所以你现在有了以下进程树:

parent
    childls
        childSort
    childSort

在childls和childls-> childSort中,childls_pid为0,因此它们都执行运行executeLs()的case 0:子句.

您需要将第二个fork移动到仅在原始父级中运行的代码中.您可以在第一个switch语句之后将其移动到.

您需要关闭管道FD的原因是因为管道并非真正关闭,直到所有打开它的进程关闭它.如果子进程的管道的写入结束打开,那么将阻止它在管道上读取EOF.

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

// function declarations
void executeLs(int data_pipe[]);
void executeSort(int data_pipe[]);

int main(){

    int data_pipe[2]; // array storing the file descriptors
    int childls_pid; // ls child process
    int childSort_pid; // sort child process
    int rc; // return vaue of the pipe
    int child_status1;
    int child_status2;

    rc = pipe(data_pipe);
    if(rc == -1){
        perror("pipe");
        exit(1);
    }

    childls_pid = fork();

    // Ls Child process
    switch(childls_pid) {
    case -1:
        perror("fork childLs Error");
        exit(1);
    case 0:
        // inside of child process
        executeLs(data_pipe);
        exit(0);
    default:
        break;
    }

    childSort_pid = fork();

    // Sort child process
    switch(childSort_pid) {
    case -1:
        perror("fork childSort Error");
        exit(1);
    case  0:
        executeSort(data_pipe);
        exit(0);
    default:
        wait(&child_status2);
    }
    return 0;
}

void executeLs(int data_pipe[]){

    // Closes the read file descriptor
    close(data_pipe[0]);

    dup2(data_pipe[1], STDOUT_FILENO);

    // confused as to why this is necessary
    close(data_pipe[1]);

    execlp("ls", "ls", "-1", NULL);
}

void executeSort(int data_pipe[]){

    // close the write file descriptor
    close(data_pipe[1]);

    dup2(data_pipe[0], STDIN_FILENO);
    close(data_pipe[0]);
    execlp("sort","sort", NULL);
}
点赞