How to run a process and get its output using c++ libboost?

送分小仙女□ 提交于 2019-12-24 08:46:49

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!