问题
I'm trying to run an external shell command and read its output using the Boost libraries for C++ but it seems that either the command is not running or I just can't access the output. I'm using their documentation as example and wrote this:
#include <boost/process.hpp>
namespace bp = boost::process;
bool is_process_running(std::string p_name){
string cmd = "ps aux 2>&1";
bp::ipstream out;
std::string line;
bp::child c(cmd, bp::std_out > out);
// the while is supposed to read each line of the output
// but the execution doesn't enter here
while(c.running() && std::getline(out, line) && !line.empty())
{
if(line.find(p_name) != std::string::npos)
{
return true;
}
}
c.wait();
return false;
}
The goal is to verify each line output of ps aux
and search if a process is running. So, what could be the problem here? Or, can you provide a simple snippet for doing this?
回答1:
Simply use a shell (or use bp::system
):
Live On Coliru
#include <boost/process.hpp>
namespace bp = boost::process;
bool is_process_running(std::string p_name){
std::vector<std::string> args { "-c", "ps aux 2>&1" };
bp::ipstream out;
bp::child c(bp::search_path("sh"), args, bp::std_out > out);
for (std::string line; c.running() && std::getline(out, line);) {
if (line.find(p_name) != std::string::npos) {
return true;
}
}
c.wait();
return false;
}
#include <iostream>
int main() {
std::cout << "bogus: " << is_process_running("bogus") << "\n";
std::cout << "a.out: " << is_process_running("a.out") << "\n";
}
Prints
bogus: 0
a.out: 1
回答2:
I've had this issue... I could only get process to work using boost::asio.
Here's the code, hopefully that will help. The code below handles all three of the child process's streams.
The only external is exename_, and tstring is a std::basic_string<TCHAR>.
void UBC::Run(
const tstring& args,
const std::string& input,
std::string& output,
std::string& error)
{
using namespace boost;
asio::io_service ios;
std::vector<char> vOut(128 << 10);
auto outBuffer{ asio::buffer(vOut) };
process::async_pipe pipeOut(ios);
std::function<void(const system::error_code & ec, std::size_t n)> onStdOut;
onStdOut = [&](const system::error_code & ec, size_t n)
{
output.reserve(output.size() + n);
output.insert(output.end(), vOut.begin(), vOut.begin() + n);
if (!ec)
{
asio::async_read(pipeOut, outBuffer, onStdOut);
}
};
std::vector<char> vErr(128 << 10);
auto errBuffer{ asio::buffer(vErr) };
process::async_pipe pipeErr(ios);
std::function<void(const system::error_code & ec, std::size_t n)> onStdErr;
onStdErr = [&](const system::error_code & ec, size_t n)
{
error.reserve(error.size() + n);
error.insert(error.end(), vErr.begin(), vErr.begin() + n);
if (!ec)
{
asio::async_read(pipeErr, errBuffer, onStdErr);
}
};
auto inBuffer{ asio::buffer(input) };
process::async_pipe pipeIn(ios);
process::child c(
tstring(exeName_) + _T(" ") + args,
process::std_out > pipeOut,
process::std_err > pipeErr,
process::std_in < pipeIn
);
asio::async_write(pipeIn, inBuffer,
[&](const system::error_code & ec, std::size_t n)
{
pipeIn.async_close();
});
asio::async_read(pipeOut, outBuffer, onStdOut);
asio::async_read(pipeErr, errBuffer, onStdErr);
ios.run();
c.wait();
}
来源:https://stackoverflow.com/questions/52187867/how-to-run-a-process-and-get-its-output-using-c-libboost