【发布时间】:2011-04-22 11:55:33
【问题描述】:
我正在用 C++(主要是 C)在模拟文件系统上实现管道。它需要在主机外壳中运行命令,但在模拟文件系统上执行管道本身。
我可以使用pipe()、fork() 和system() 系统调用来实现这一点,但我更喜欢使用popen()(它处理创建管道、分叉进程以及将命令传递给贝壳)。这可能是不可能的,因为(我认为)我需要能够从管道的父进程写入,在子进程端读取,从子进程写回输出,最后从父进程读取该输出。我系统上popen() 的手册页说双向管道是可能的,但我的代码需要在旧版本仅支持单向管道的系统上运行。
通过上面的单独调用,我可以打开/关闭管道来实现这一点。 popen() 可以吗?
举个简单的例子,要运行ls -l | grep .txt | grep cmds,我需要:
- 打开管道和进程在主机上运行
ls -l;回读其输出 - 将
ls -l的输出传送回我的模拟器 - 在
ls -l的管道输出上打开一个管道和进程以在主机上运行grep .txt - 通过管道将其输出回模拟器(卡在此处)
- 在
grep .txt的管道输出上打开一个管道和进程以在主机上运行grep cmds - 通过管道将其输出回模拟器并打印出来
人爆表
来自 Mac OS X:
popen()函数“打开”一个 通过创建一个双向的过程 管道、分叉和调用 shell。 以前的popen()打开的任何流 父进程中的调用被关闭 在新的子进程中。 历史上,popen()已实现 带单向管;因此, 仅popen()的许多实现 允许模式参数指定 阅读或写作,而不是两者兼而有之。因为popen()现在使用 双向管道,模式参数 可以请求双向数据流。 mode 参数是一个指向 必须为空终止的字符串 'r' 用于阅读,'w' 用于写作,或 'r+' 用于读写。
【问题讨论】:
-
忽略这本糟糕的手册,这使得管道的单向性看起来像是一种遗留行为。您的实现行为是非标准的,在其他环境中可能永远不会得到支持。只需自己设置管道、fork 和 exec,一切都会很开心。
-
这整个线程都是由win组成的,所有答案和问题都值得+1。
-
我刚刚在 Ubuntu 13.04 上做了一个 man popen,它指出:
Since a pipe is by definition unidirectional, the type argument may specify only reading or writing, not both; the resulting stream is correspondingly read-only or write-only.我很惊讶这是“旧”的 popen...