简体   繁体   English

程序卡在管道上(exec ls grep sort)

[英]Program stuck on Pipe (exec ls grep sort)

I'm trying to make a program that executes the following commands connecting the output of one to the input of the next using pipes and taking two arguments DIR (directory) and ARG (filetype, example: jpg). 我正在尝试制作一个程序,该程序执行以下命令,使用管道将一个输出连接到下一个输入,并接受两个参数DIR (目录)和ARG (文件类型,例如:jpg)。

ls DIR -laR | ls DIR -laR | grep ARG | grep ARG | sort 分类

Here's the code: 这是代码:

int main(int argc, char *argv[]) {

    if (argc != 3) {
        printf("Invalid arguments. <dir> <arg>\n");
        exit(1);
    }

    int pipe_fd1[2];
    int pipe_fd2[2];
    pid_t ls_pid, grep_pid;
    int status;

    pipe(pipe_fd1);
    pipe(pipe_fd2);

    ls_pid = fork();
    if (ls_pid == 0) { //first child ls DIR -laR
        dup2(pipe_fd1[1], STDOUT_FILENO);
        close(pipe_fd1[0]);

        execlp("ls", "ls", argv[1], "-laR", NULL);

    } else if (ls_pid > 0) {
        grep_pid = fork();
        if (grep_pid == 0) { //second child grep ARG
            dup2(pipe_fd1[0], STDIN_FILENO);
            dup2(pipe_fd2[1], STDOUT_FILENO);       
            close(pipe_fd1[1]);
            close(pipe_fd2[0]);

            waitpid(ls_pid, &status, 0);    
            execlp("grep", "grep", argv[2], NULL);

        } else if (grep_pid > 0) { //parent sort
            dup2(pipe_fd2[0], STDIN_FILENO);
            close(pipe_fd2[1]);

            waitpid(grep_pid, &status, 0);
            execlp("sort", "sort", NULL);
        }

    }

    return 0;
}

It seems to be stuck? 好像卡住了吗? Not sure why? 不知道为什么吗?

You never close pipe_fd1 on the parent, so grep and sort doen't know when to stop reading input: because the pipe read and write ends are never closed on the parent, the reader blocks waiting for more input that will never arrive. 您永远不会在父pipe_fd1上关闭pipe_fd1 ,因此grepsort不知道何时停止读取输入:由于在父级上从未关闭管道的读取和写入端,因此读取器会阻塞等待更多永远不会到达的输入。 You need to close it. 您需要关闭它。

Also, you don't need waitpid() : the way pipes work ensures that input flows linearly and in order throughout the pipe. 另外,您不需要waitpid() :管道的工作方式可确保输入在整个管道中线性且有序流动。

Here's the working version with these issues addressed: 这是解决了这些问题的工作版本:

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

int main(int argc, char *argv[]) {

    if (argc != 3) {
        printf("Invalid arguments. <dir> <arg>\n");
        exit(1);
    }

    int pipe_fd1[2];
    int pipe_fd2[2];
    pid_t ls_pid, grep_pid;

    pipe(pipe_fd1);

    ls_pid = fork();
    if (ls_pid == 0) { //first child ls DIR -laR
        dup2(pipe_fd1[1], STDOUT_FILENO);
        close(pipe_fd1[0]);
        execlp("ls", "ls", argv[1], "-laR", NULL);

    } else if (ls_pid > 0) {
        dup2(pipe_fd1[0], STDIN_FILENO);
        close(pipe_fd1[1]);

        pipe(pipe_fd2);
        grep_pid = fork();

        if (grep_pid == 0) { //second child grep ARG
            dup2(pipe_fd2[1], STDOUT_FILENO);
            close(pipe_fd2[0]);  
            execlp("grep", "grep", argv[2], NULL);

        } else if (grep_pid > 0) { //parent sort
            dup2(pipe_fd2[0], STDIN_FILENO);
            close(pipe_fd2[1]);
            execlp("sort", "sort", NULL);
        }

    }

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM