微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我正在努力制作一个像 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,但我的问题是:如何为 grep 保存 stdout 而不在第一个管道上重复 stdout?

如果我在 dup2(fd[1],1) cat 上的 dup 在第一个管道中不起作用,有人可以帮助我使此代码起作用吗?并尽可能使其类似于 bash heredoc。

解决方法

如何在不重复第一个管道上的标准输出的情况下为 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
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。