【问题标题】:Pipe implementation管道实现
【发布时间】:2011-02-09 05:11:57
【问题描述】:

我正在尝试实现一个支持管道的 linux shell。我已经完成了简单的命令、后台运行的命令、重定向,但仍然缺少管道。

我已经阅读过它并看到了一些 sn-ps 代码,但仍然无法找出可行的解决方案。

到目前为止我所拥有的:

int fd[2];

pipe(fd);

pid_t pid = fork();

if (pid == -1)  
   return -1;  

if (pid == 0)  
{  
   close(fd[1]); //close write to pipe, in child
   execlp("cat", "cat", "names.txt", NULL);
}

else
{
   close(fd[0]); //close read from pipe, in parent
   execlp("sort", "sort", NULL);
}  

我是一个新手程序员,你可能会说,当我在编写一些我不太了解的东西时,显然是这样,我喜欢从非常简单和具体的东西开始,然后从那里开始构建.

因此,在能够在管道中实现三个或更多不同的命令之前,我希望能够计算“ls names.txt | sort”或类似的东西,其中 names.txt 是一个按字母顺序排列的名称文件.

更新了代码,但还是不行。

谢谢。

【问题讨论】:

    标签: c linux shell pipe piping


    【解决方案1】:

    您需要将一个孩子的标准输出替换为管道的写入端,将另一个孩子的标准输入替换为读取端:

    if (pid == 0)  
    {  
       close(fd[0]); //close read from pipe, in parent
       dup2(fd[1], STDOUT_FILENO); // Replace stdout with the write end of the pipe
       close(fd[1]); // Don't need another copy of the pipe write end hanging about
       execlp("cat", "cat", "names.txt", NULL);
    }
    else
    {
       close(fd[1]); //close write to pipe, in child
       dup2(fd[0], STDIN_FILENO); // Replace stdin with the read end of the pipe
       close(fd[0]); // Don't need another copy of the pipe read end hanging about
       execlp("sort", "sort", NULL);
    } 
    

    【讨论】:

    • 我情不自禁,但在我看来,情况正好相反。为什么我们要把 cat 的标准输入和 sort 的标准输出连接起来。不是反过来吗?例如。猫的输出进入排序的输入。
    • @VicenteAdolfoBoleaSánchez:这可能更有意义,我已经更新了答案。
    • 哦,太好了!明白了:)
    【解决方案2】:

    查看@987654321@ 标准库调用。这用于创建管道。您当然必须在fork()fork()之前完成部分工作,以便子进程正确继承文件描述符。

    还要注意@987654322@的参数顺序:

    int dup2(int oldfd, int newfd);
    

    dup2() 使 newfd 成为 oldfd 的副本,必要时先关闭 newfd

    【讨论】:

    • 我已经知道了,只是忘记在代码中添加管道语句。你现在有什么建议?谢谢。
    • 我认为 dup2(0, fd[0]) 正在将应该去 stdout 的内容复制到 fd[0],这是进程的输入。我想这就是我想要的,对吧?
    • @nunos: dup2() 不进行复制,它复制文件描述符。由于 fd[0] 是新创建管道的一端的 fd,因此关闭它没有多大意义,就像 dup2() 一样。
    • 我现在明白了。我已经更新了代码。你能看看并报告我缺少的东西吗?再次感谢您的帮助。
    • 如果你认为这个答案有帮助,你应该投票。 :) 我认为您的原始代码更好,您 想要 使用 dup2() 但我试图暗示您的论点是错误的。
    猜你喜欢
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多