web-dev-qa-db-ja.com

popen()は、実行されたコマンドの出力をcoutに書き込みます

別のプロセスを開いて出力を取得する必要があるアプリケーションを書いています。オンラインでどこを読んでも私はpopenを使用してファイルから読み取る必要があります。

しかし、それを読むことはできません。コマンドの出力は、呼び出し側アプリケーションのコンソールウィンドウに出力されます。以下は私が使用しているコードです。デバッグ用にプリントをいくつか追加しました。

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <array>

int main()
{
    // some command that fails to execute properly.
    std::string command("ls afskfksakfafkas");

    std::array<char, 128> buffer;
    std::string result;

    std::cout << "Opening reading pipe" << std::endl;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Couldn't start command." << std::endl;
        return 0;
    }
    while (fgets(buffer.data(), 128, pipe) != NULL) {
        std::cout << "Reading..." << std::endl;
        result += buffer.data();
    }
    auto returnCode = pclose(pipe);

    std::cout << result << std::endl;
    std::cout << returnCode << std::endl;

    return 0;
}

読み取り値が実際にmy coutに出力されることはなく、結果は空の文字列になります。端末にコマンドの出力がはっきり表示されます。コマンドが正常に終了した場合、動作は期待どおりです。ただし、エラーの場合の出力のみをキャプチャします。

5
John Smith

Popenはstderrだけをキャプチャせず、stdoutだけをキャプチャします。 stderrをstdoutにリダイレクトすると、問題が修正されます。

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <array>

int main()
{
    std::string command("ls afskfksakfafkas 2>&1");

    std::array<char, 128> buffer;
    std::string result;

    std::cout << "Opening reading pipe" << std::endl;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Couldn't start command." << std::endl;
        return 0;
    }
    while (fgets(buffer.data(), 128, pipe) != NULL) {
        std::cout << "Reading..." << std::endl;
        result += buffer.data();
    }
    auto returnCode = pclose(pipe);

    std::cout << result << std::endl;
    std::cout << returnCode << std::endl;

    return 0;
}
9
John Smith

コマンド文字列の最後に「2>&1」を追加する必要があります

command.append(" 2>&1");

完全な例があります https://www.jeremymorgan.com/tutorials/c-programming/how-to-capture-the-output-of-a-linux-command-in-c/

5
Антон М