首页 > 解决方案 > Boost 1.71.0:如何获得进程输出?

问题描述

Ubuntu 18.04我有这样的代码可以正常工作Boost 1.65.0

// See https://www.boost.org/doc/libs/1_65_0/doc/html/boost_process/tutorial.html
std::pair<int, std::string> runCommandAndGetOutput(const std::string & cmd, const std::vector<std::string> & args)
{
  namespace bp = boost::process;
  boost::asio::io_service ios;
  std::future<std::string> data;
  bp::child c(cmd, bp::args(args), bp::std_in.close(), bp::std_out > data, bp::std_err > bp::null, ios);
  ios.run();
  if (c.exit_code()) {
    std::cerr << "Command '" << cmd << "' failed with return value: " << c.exit_code();
  }
  return { c.exit_code(), data.get() };
}

但是,在升级到Ubuntu 20.04and之后,Boost 1.71.0它不再编译,因为它似乎已boost::asio::io_service被弃用并且不再存在。

谷歌搜索后,我意识到我必须boost::asio::io_context改用。

行:

std::pair<int, std::string> runCommandAndGetOutput(const std::string & cmd, const std::vector<std::string> & args)
{
  namespace bp = boost::process;
  boost::asio::io_context ioc;
  std::future<std::string> data;
  bp::child c(cmd, bp::args(args), bp::std_in.close(), bp::std_out > data, bp::std_err > bp::null, ioc);
  ioc.run();
  if (c.exit_code()) {
    std::cerr << "Command '" << cmd << "' failed with return value: " << c.exit_code();
  }
  return { c.exit_code(), data.get() };
}

这可以编译,但不起作用。尝试运行 eg返回没有任何意义的/usr/bin/free退出代码。383

使这变得困难的是,文档Boost 1.71.0仍在使用io_service

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_process/tutorial.html

有谁知道这应该怎么做?

标签: c++ubuntuc++11boostboost-asio

解决方案


你需要wait直到孩子完成。

exit_code- "获取exit_code。如果孩子没有被等待或被终止,则返回值没有任何意义。 "

#include "boost/process.hpp"

#include <iostream>

std::pair<int, std::string> runCommandAndGetOutput(
    const std::string& cmd, const std::vector<std::string>& args) {
    namespace bp = boost::process;
    boost::asio::io_context ioc;
    std::future<std::string> data;
    bp::child c(cmd, bp::args(args), bp::std_in.close(), bp::std_out > data,
                bp::std_err > bp::null, ioc);
    ioc.run();
    
    c.wait();                        // <---- here

    if(c.exit_code()) {
        std::cerr << "Command '" << cmd
                  << "' failed with return value: " << c.exit_code();
    }
    return {c.exit_code(), data.get()};
}

int main() {
    auto rv = runCommandAndGetOutput("/usr/bin/free", {});

    std::cout << "\n----------\n" << rv.second << '\n' << rv.first << '\n';
}

推荐阅读