【发布时间】:2021-05-29 09:56:37
【问题描述】:
给出以下答案(第一个 c++11 答案):
How do I execute a command and get the output of the command within C++ using POSIX?
为了您的方便,这里是实现:
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}
这非常适合执行命令(例如std::string res = exec("ls");)并将标准输出转换为字符串。
但它不做的是获取命令返回码(通过/失败整数)或标准错误。理想情况下,我想要一种方法来获取所有三个(返回代码、标准输出、标准错误)。
我会满足于标准输出和标准错误。我在想我需要添加另一个管道,但我真的看不到第一个管道是如何设置来获取标准输出的,所以我想不出如何改变它来获取两者。
任何人有任何想法如何做到这一点,或可能有效的替代方法?
更新
查看我的完整示例here 的输出:
Start
1 res: /home
2 res: stdout
stderr
3 res:
End
您可以看到 3 res: 不像 2 res: stdout 那样打印 stderr,但 stderr 只是由进程(而不是我的程序)在单独的行上转储到屏幕上。
外部库
我真的不想使用像 Qt 和 boost 这样的外部库——主要是因为我想要它的可移植性,而且我从事的许多项目都不使用 boost。但是,我将标记包含这些选项的解决方案,因为它们对其他用户有效:)
使用评论/答案的完整解决方案
感谢大家的回答/cmets,这是修改后的解决方案(并且可以运行):
【问题讨论】:
-
boost是一个选项吗?如果是这样,您可能想看看boost::process。 -
@user1810087 嗯...不,我宁愿保持纯 c++/c++11。在我的特定项目中,我们选择不使用 boost 库。
-
有一种可能的解决方法。您可以通过将“2>&1”附加到您的 cmd 来将标准错误重定向到标准输出。这会满足您的需求吗?
-
@Alex 该死的......这很聪明,我一直在 bash 脚本中使用它,但没想到在这里使用它!......如果它有效,那么是的:)..我仍然会建议做一个 c++ 版本,但这是一个很好的解决方法,先生......现在测试......
-
@Alex 效果很好 - 请添加您的评论作为答案,我会投票赞成
标签: c++ c++11 process stdout stderr