【发布时间】:2018-07-31 04:32:07
【问题描述】:
我正在运行 MacOS,并希望执行“ps aux”命令并通过我的应用程序获取其输出。我写了一个使用 popen 函数执行命令的方法:
std::string exec(const char* cmd) {
char buffer[128];
std::string result = "";
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::runtime_error("popen() failed!2");
try {
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
return result;
}
我有一个不断运行 exec("ps aux") 函数的循环。问题是来自 popen 的管道没有关闭,我已经使用终端中的“lsof”命令进行了检查。大约 20 秒后,应用程序打开了大约 300 个文件描述符,这会阻止应用程序从循环中打开更多管道(运行“ps aux”命令)。
我发现,exec 函数适用于其他命令(管道正确关闭),例如“netstat”,因此它必须是“ps aux”命令中阻止管道关闭的东西.
我已经对这个问题进行了很多搜索,但没有找到任何解决方案。 有人可以指出我正确的方向吗?
谢谢!
【问题讨论】:
-
可能与您的问题无关,但请花点时间阅读Why is “while ( !feof (file) )” always wrong?
-
也无关 - 但我个人会使用 RAII 类而不是显式的 catch/rethrow,比如
struct PipeCloser { void operator()(FILE* f) { pclose(f); } }; using PipeUniquePtr = std::unique_ptr<FILE, PipeCloser>;