我目前正在开发一个跨平台项目。在Windows上,我有一个运行进程/脚本(使用命令行)的类,等待它结束,并从stdout / stderr读取所有内容到缓冲区。然后我将输出打印到自定义“控制台”。注意:这不是将子标准输出重定向到父标准输出,只是从子标准输出到父标记的管道。
我是OSX / unix-like api的新手,但我可以理解做这样的事情的规范方式是分叉和管道标准。但是,我不想将它重定向到stdout,我想捕获输出..它应该像这样工作(伪代码,与unix函数完全相似的相似):
class program
{
string name, cmdline;
string output;
program(char * name, char * cmdline)
: name(name), cmdline(cmdline) {};
int run()
{
// run program - spawn it as a new process
int pid = exec(name, cmdline);
// wait for it to finish
wait(pid);
char buf[size];
int n;
// read output of program's stdout
// keep appending data until there's nothing left to read
while (read(pid, buf, size, &n))
output.append(buf, n);
// return exit code of process
return getexitcode(pid);
}
const string & getOutput() { return output; }
};
我将如何在OSX上执行此操作?
E:
好吧所以我研究了相关的api,似乎某种fork / exec组合是不可避免的。手头的问题是我的进程非常大并且分叉它似乎是一个坏主意(我发现如果父进程占用系统的50%以上,某些unix实现无法做到这一点RAM)。
我不能以任何方式避免这个计划吗?我看到vfork()可能是一个可能的竞争者,所以也许我可以尝试使用vfork来模仿popen()函数。但话说回来,大多数手册都说vfork可能只是fork()
答案 0 :(得分:0)
你有一个库调用来做到这一点:popen。它将为您提供文件描述符的返回值,您可以读取该描述符直到eof。它是stdio的一部分,因此您可以在OSX上执行此操作,但也可以在其他系统上执行此操作。只记得pclose()描述符。
#include <stdio.h>
FILE * popen(const char *command, const char *mode);
int pclose(FILE *stream);
如果你想保持绝对没有重定向的输出,我们唯一能想到的是使用像“tee”这样的命令 - 一个将输出分成文件但保留自己的标准输出的命令。在代码中实现它也相当容易,但在这种情况下可能没有必要。