Como executar um comando e obter o código de retorno stdout e stderr do comando em C ++
Dada a seguinte resposta (primeira resposta c ++ 11):
Como executar um comando e obter saída de comando no C ++ usando POSIX?
Aqui está a implementação para sua conveniência:
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}
Isso funciona muito bem para executar um comando (por exemplo,std::string res = exec("ls");
) e coloque o stdout em uma string.
Mas o que ele não faz é obter o código de retorno do comando (número inteiro aprovado / reprovado) ou o stderr. Idealmente, eu gostaria de uma maneira de obter todos os três (código de retorno, stdout, stderr).
Eu aceitaria stdout e stderr. Eu estou pensando que eu preciso adicionar outro canal, mas não consigo ver como o primeiro canal está configurado para ficar stdout, então não consigo pensar em como alterá-lo para obter os dois.
Alguém tem alguma idéia de como fazer isso, ou abordagens alternativas que podem funcionar?
atualizar
Veja meu exemplo completoaqui com a saída:
Start
1 res: /home
2 res: stdout
stderr
3 res:
End
Você pode ver isso3 res:
não imprime stderr da mesma maneira que2 res: stdout
mas stderr é despejado na tela em uma linha separada pelo processo (e não pelo meu programa).
Libs externos
Eu realmente não quero usar bibliotecas externas como Qt e boost - principalmente porque quero a portabilidade e também muitos projetos nos quais trabalho não usam o boost. No entanto, marcarei soluções que contêm essas opções, pois são válidas para outros usuários :)
Solução completa usando comentários / resposta
Obrigado a todos por suas respostas / comentários, aqui está a solução modificada (e executável):