web-dev-qa-db-fra.com

popen () écrit la sortie de la commande exécutée dans cout

J'écris une application qui doit ouvrir un autre processus et obtenir sa sortie. En ligne partout où je lis, je dois utiliser popen et lire le fichier.

Mais je ne peux pas en lire. La sortie de la commande est sortie dans la fenêtre de console de l'application appelante. Voici le code que j'utilise. J'ai ajouté quelques impressions pour déboguer.

#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;
}

La lecture n'est jamais réellement imprimée dans mon cout et le résultat est une chaîne vide. Je vois clairement la sortie de la commande dans mon terminal. Si la commande se termine normalement, le comportement est comme prévu. Mais je capture uniquement la sortie pour les cas d'erreur.

5
John Smith

Popen ne capture pas stderr uniquement stdout. Rediriger stderr vers stdout résout le problème.

#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

Vous devez ajouter "2> & 1" à la fin de la chaîne de commande

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

il y a un exemple complet https://www.jeremymorgan.com/tutorials/c-programming/how-to-capture-the-output-of-a-linux-command-in-c/

5
Антон М