如何使 cat 和 grep 在 c 中的第一个和第二个管道中工作,就像 bash 中的 heredoc <<

Posted

技术标签:

【中文标题】如何使 cat 和 grep 在 c 中的第一个和第二个管道中工作,就像 bash 中的 heredoc <<【英文标题】:how make cat and grep work in the first and the second pipe in c writing like heredoc in bash << 【发布时间】:2021-09-21 19:45:44 【问题描述】:

我正在制作一个类似 bash 的 shell,但我无法解决 heredoc

        void pipeline()
    
        int i = 0;
        int fd[2];
        pid_t pid;
        int fdd = 0;
    
        while (i < 2)
        
            pipe(fd);
            pid = fork();
            if (pid == 0)
               
                //dup2(fd[1],1); if i dup in the first pipe cat dont finalize
                if (i == 0)
                    dup2(fd[0],0);
                write(fd[1], "hello\nhow\nare\nyou\n", 17);
                close(fd[0]);
                close(fd[1]);
                dup2(fdd, 0);
                if (i == 0)
                    execlp("cat", "cat", NULL);
                else
                    execlp("grep", "grep", "you" , NULL);
                perror("error");
                exit(1);
            
            else 
               
                close(fd[1]);
                fdd = fd[0];
                wait(NULL);
                i++;
            
        
    
    
    int main(int *argc, char **argv, char **env)
    
        pipeline();

我知道 cat 和 grep 需要 EOF 才能运行;我正在做的是在 stdin 中编写并运行 cat,但我的问题是:如何在不重复第一个管道上的 stdout 的情况下为 grep 保存 stdout?

如果我 dup on dup2(fd[1],1) cat 在第一个管道中不起作用,有人可以帮助我使这段代码正常工作吗?并尽可能使其与 bash heredoc 相似。

【问题讨论】:

【参考方案1】:

如何为 grep 保存标准输出而不在第一个管道上复制标准输出?

我会重新安排子进程的创建从最右边到最左边 - 然后首先创建 grep 并可以输出到初始输出描述符。一个必要的改变是在等待一个子进程之前以及写入之前运行所有子进程,这样即使管道缓冲区不足以满足 heredoc 的需求,也不会出现死锁。

void pipeline()

    int i = 2;  // create children from last to first
    int fd[2];
    pid_t pid;
    int fdd = 1;    // output of last child is STDOUT
    while (i--)
    
        pipe(fd);
        pid = fork();
        if (pid == 0)
        
            dup2(fdd, 1);   // child's output
            dup2(fd[0], 0);
            close(fd[0]);
            close(fd[1]);
            if (i == 0)
                execlp("cat", "cat", "-A", NULL);
            else
                execlp("grep", "grep", "you" , NULL);
            perror("error");
            exit(1);
        
        if (fdd != 1) close(fdd);   // close if a pipe write end
        fdd = fd[1];    // preceding child's output is pipe write end
        close(fd[0]);
    
    write(fd[1], "hello\nhow\nare\nyou\n", 17);
    close(fd[1]);   // signal EOF to child
    while (wait(NULL) > 0) ;    // wait for all children

【讨论】:

以上是关于如何使 cat 和 grep 在 c 中的第一个和第二个管道中工作,就像 bash 中的 heredoc <<的主要内容,如果未能解决你的问题,请参考以下文章

Linux三剑客

Linux三剑客

Linux三剑客

在Bash中使用cat和grep命令

linux如何查看所有的用户和组信息

linux如何查看所有的用户和组信息?