Piped输出重复

时间:2015-11-19 20:52:46

标签: c

有人可以向我解释为什么我的输出在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);
}

1 个答案:

答案 0 :(得分:2)

原因是您要求的流程超出预期。当你这样做时:

fork()

您在原始父流程和第一个parent childls childSort childSort 创建的流程中执行了第二个childls。所以你现在有了以下过程树:

childls->childSort

childls_pidcase 0:中,executeLs()为0,因此它们都执行运行fork的{​​{1}}子句。

您需要将第二个switch移动到仅在原始父级中运行的代码中。您只需将其移至第一个EOF语句后即可。

您需要关闭管道FD的原因是因为管道并非真正关闭,直到所有打开它的进程关闭它。如果子进程的管道的写入结束打开,那么它将使其无法读取管道上的#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); }

<select id="locationSelector" name="locationSelector">
   <option value=0 >All</option>
   <option value=1>Lahore</option>
   <option value=2>Karachi</option>
</select>
相关问题