简体   繁体   中英

Execute a command with C++ and capture the output and the status

How can I execute a system command with C++ and capture its output and the status. It should look something like this:

Response launch(std::string command);

int main()
{
    auto response = launch("pkg-config --cflags spdlog");
    std::cout << "status: " << response.get_status() << '\n'; // -> "status: 0"
    std::cout << "output: " << response.get_output() << '\n'; // -> "output: -DSPDLOG_SHARED_LIB -DSPDLOG_COMPILED_LIB -DSPDLOG_FMT_EXTERNAL"
}

Using std::system you can only get status. I also tried this solution but it only captures the output and it seems to be very "hacky" and not safe. There must be a better way to do it but I haven't found one yet. If there isn't a simple and portable solution, I would also use a library.

I found a way with redirecting the output to a file and reading from it:

#include <string>
#include <fstream>
#include <filesystem>

struct response
{
    int status = -1;
    std::string output;
};

response launch(std::string command)
{
    // set up file redirection
    std::filesystem::path redirection = std::filesystem::absolute(".output.temp");
    command.append(" &> \"" + redirection.string() + "\"");

    // execute command
    auto status = std::system(command.c_str());

    // read redirection file and remove the file
    std::ifstream output_file(redirection);
    std::string output((std::istreambuf_iterator<char>(output_file)), std::istreambuf_iterator<char>());
    std::filesystem::remove(redirection);

    return response{status, output};
}

Still seems a bit "hacky" but it works. I would love to see a better way without creating and removing files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM