【发布时间】:2009-04-17 21:04:42
【问题描述】:
我正在开发一个使用 execvp 执行程序的程序。它需要捕获子进程的结果并在主进程中解析它们。似乎有一种方法,使用命名管道和复制。我正在努力寻找一个很好的例子,但到目前为止还没有运气。如果有人对此有任何指示、链接和/或建议,我将不胜感激。
【问题讨论】:
标签: unix named-pipes
我正在开发一个使用 execvp 执行程序的程序。它需要捕获子进程的结果并在主进程中解析它们。似乎有一种方法,使用命名管道和复制。我正在努力寻找一个很好的例子,但到目前为止还没有运气。如果有人对此有任何指示、链接和/或建议,我将不胜感激。
【问题讨论】:
标签: unix named-pipes
你不需要命名管道;未命名的管道工作得很好。实际上,您通常可以只使用popen 而不是自己使用pipe/fork/dup/exec。 popen 是这样工作的(尽管你的 libc 的实现可能有更多的错误检查):
FILE *popen(const char *command, const char *type) {
int fds[2];
const char *argv[4] = {"/bin/sh", "-c", command};
pipe(fds);
if (fork() == 0) {
close(fds[0]);
dup2(type[0] == 'r' ? 0 : 1, fds[1]);
close(fds[1]);
execvp(argv[0], argv);
exit(-1);
}
close(fds[1]);
return fdopen(fds[0], type);
}
这将创建一个未命名的管道和forks。在孩子中,它将标准输出(或标准输入)重新附加到管道的一端,然后execs 孩子。父级可以简单地从管道的另一端读取(或写入)。
【讨论】:
dup2 手册页:“使newfd 成为oldfd 的副本,如有必要,首先关闭newfd”所以这应该有效无需先手动关闭 stdout/stdin。
你不能只使用 popen() 吗?
【讨论】:
这是一个简单的例子,演示如何使用 popen 来实现您的目标。只需将比“echo”更有趣的东西作为命令:)
#include <stdio.h>
int main()
{
char buf[100];
int i = 0;
FILE *p = popen("echo \"Test\"","r");
if (p != NULL )
{
while (!feof(p) && (i < 99) )
{
fread(&buf[i++],1,1,p);
}
buf[i] = 0;
printf("%s",buf);
pclose(p);
return 0;
}
else
{
return -1;
}
}
【讨论】: