2010-04-17 64 views
8

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

我已经阅读了这篇文章并看了一些代码片段,但仍然无法理清一个可行的解决方案。

我到目前为止有:

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是一个名称文件alfabetically无序的。

更新的代码,但仍然不起作用。

谢谢。

回答

9

您需要更换一个第一封闭newfd孩子的标准输出与管道的写入结束,另一个孩子的标准读物与读取结束:

if (pid == 0) 
{ 
    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("cat", "cat", "names.txt", NULL); 
} 
else 
{ 
    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("sort", "sort", NULL); 
} 
4

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

还要注意的参数的顺序,以dup2()

int dup2(int oldfd, int newfd); 

DUP2()使newfd是oldfd的副本,如果必要的话

+0

我已经知道了,只是忘了将管道语句添加到代码中。你现在建议什么?谢谢。 – nunos 2010-04-17 19:15:46

+0

我以为dup2(0,fd [0])正在将应该转到stdout的内容复制到fd [0],这是进程的输入。我想那是我想要的,对吧? – nunos 2010-04-17 19:26:34

+0

@nunos:dup2()不执行复制,它复制*文件描述符*。由于fd [0]是新创建的管道一端的fd,因此关闭该管道并没有多大意义,因为dup2()会执行此操作。 – unwind 2010-04-17 19:37:38