Boost 1.71.0下如何正确实现获取外部进程执行输出的功能
问题根因
你遇到的异常退出码383是boost::process::exit_code::still_active常量的固定值,代表调用exit_code()时子进程尚未结束,无法获取真实退出状态。
出现该问题的原因是Boost 1.71对io_context的适配逻辑和旧版io_service不同:旧版io_service::run()会等待进程退出、IO读取所有异步事件全部完成后才返回;但新版io_context::run()在标准输出读取完成后就会提前返回,此时子进程可能还未完全退出,直接调用exit_code()就会拿到无效值。
正确实现方案
方案1:保留io_context,新增进程等待逻辑
仅需要在ioc.run()后加一句c.wait(),等待进程完全退出后再获取退出码即可:
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(); // 等待子进程完全退出 int exit_code = c.exit_code(); if (exit_code != 0) { std::cerr << "Command '" << cmd << "' failed with return value: " << exit_code; } return { exit_code, data.get() }; }
方案2:简化实现,去掉asio依赖
如果没有其他异步逻辑需求,这个场景可以完全不用io_context,代码更简洁:
std::pair<int, std::string> runCommandAndGetOutput(const std::string & cmd, const std::vector<std::string> & args) { namespace bp = boost::process; 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); c.wait(); int exit_code = c.exit_code(); if (exit_code != 0) { std::cerr << "Command '" << cmd << "' failed with return value: " << exit_code; } return { exit_code, data.get() }; }
两种方案都可以在Boost 1.71 + Ubuntu 20.04环境下正常运行,返回正确的进程退出码和标准输出内容。
内容的提问来源于stack exchange,提问作者juzzlin
相关产品推荐
相关产品推荐

