当我们使用 dup 将 STDOUT 重定向到管道时,我们这样做:
close(1); dup(fd[1]);
close(fd[0]);
close(fd[1]);
execlp("ls","-al",(char *) NULL);
但我们正在关闭管道的两端。那么如何将 STDOUT 写入管道?
因为一旦关闭了文件描述符编号 1(例如标准输出),该编号就可用于进一步dup
或open
调用。
您应该检查您的close
和dup
系统调用的结果。
当然,关闭管道的两端是没有意义的,除非您之前做了一些有用的事情(即在适当的末端读取或写入)。
请参阅open(2)、dup(2)、pipe(2)、close(2)手册页。阅读《高级 Linux 编程》一书。
在示例代码中,您没有关闭管道的两端。你正在关闭fd[0]
和fd[1]
。最初,关闭这些就足以关闭管道的两端,但不是在您复制fd[0]
. 您还必须关闭重复的 fd 才能关闭对管道的所有引用。不过那会很愚蠢:您正在准确地保持一个结束,以便 ls 可以写入。
也许您的困惑即将close()
结束?它关闭 fd,即对管道末端之一的引用。它不会关闭管道本身:这就是shutdown()
会做的。(如果你不调用shutdown,当引用它的每个fd都关闭时,管道会自动关闭。)所以,因为复制的fd仍然打开,进程可以写入管道(它没有关闭,因为三个引用中只有两个被关闭)。