最佳地从system()命令捕获stdout

时间:2020-03-06 14:38:50  来源:igfitidea点击:

我正在尝试通过system()启动一个外部应用程序,例如system(" ls")。我想捕获它的输出,以便将其发送到另一个函数进行进一步处理。用C / C ++做到这一点的最佳方法是什么?

解决方案

我不能完全确定它在标准C语言中是否可行,因为两个不同的进程通常不共享内存空间。我想到的最简单的方法是让第二个程序将其输出重定向到文本文件(程序名> textfile.txt),然后再读回该文本文件进行处理。但是,这可能不是最好的方法。

编辑:误读问题,因为希望将输出传递给另一个程序,而不是另一个函数。 popen()几乎可以肯定是我们想要的。

系统使我们可以完全访问shell。如果我们想继续使用它,可以
通过system(" ls> tempfile.txt")将其输出重定向到一个临时文件,但是选择一个安全的临时文件很麻烦。或者,我们甚至可以通过另一个程序重定向它:system(" ls | otherprogram");

有些人可能会推荐popen()命令。如果可以自己处理输出,这就是我们想要的:

FILE *output = popen("ls", "r");

这将为我们提供一个FILE指针,我们可以从中读取命令的输出。

我们还可以使用pipe()调用与fork()一起创建新进程来创建连接,dup2()更改它们的标准输入和输出,exec()来运行新程序,以及wait()在主程序中等待它们。这只是像外壳程序一样设置管道。有关详细信息和示例,请参见pipe()手册页。

在Windows中,而不是使用system(),而是使用CreateProcess,将输出重定向到管道并连接到管道。

我猜这也可以通过POSIX方式实现吗?

从popen手册中:

#include <stdio.h>

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

尝试popen()函数。它执行类似于system()的命令,但将输出定向到新文件中。返回指向流的指针。

FILE *lsofFile_p = popen("lsof", "r");

  if (!lsofFile_p)
  {
    return -1;
  }

  char buffer[1024];
  char *line_p = fgets(buffer, sizeof(buffer), lsofFile_p);
  pclose(lsofFile_p);

函数popen()pclose()可能就是我们想要的。

以glibc手册为例。