Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I execute a command and get the output of the command within C++ using POSIX?

I am looking for a way to get the output of a command when it is run from within a C++ program. I have looked at using the system() function, but that will just execute a command. Here's an example of what I'm looking for:

std::string result = system("./some_command"); 

I need to run an arbitrary command and get its output. I've looked at boost.org, but I have not found anything that will give me what I need.

like image 889
Misha M Avatar asked Jan 26 '09 05:01

Misha M


People also ask

Which function is used for running command string from within a program in C in Unix?

system - run shell command int system (const char *command); The command is run noninteractively in a shell, output is to the terminal and your program waits for command completion.

How do I get output in C++?

C++ Output In C++, cout sends formatted output to standard output devices, such as the screen. We use the cout object along with the << operator for displaying output.

What is the difference between Popen and system?

popen() gives you control over the process's input or output file streams. system() doesn't. If you don't need to access the process's I/O, you can use system() for simplicity. system() is in C89 and C99; popen() is Posix only (though the Windows API also has one).


2 Answers

#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::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);     if (!pipe) {         throw std::runtime_error("popen() failed!");     }     while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {         result += buffer.data();     }     return result; } 

Pre-C++11 version:

#include <iostream> #include <stdexcept> #include <stdio.h> #include <string>  std::string exec(const char* cmd) {     char buffer[128];     std::string result = "";     FILE* pipe = popen(cmd, "r");     if (!pipe) throw std::runtime_error("popen() failed!");     try {         while (fgets(buffer, sizeof buffer, pipe) != NULL) {             result += buffer;         }     } catch (...) {         pclose(pipe);         throw;     }     pclose(pipe);     return result; } 

Replace popen and pclose with _popen and _pclose for Windows.

like image 111
waqas Avatar answered Oct 06 '22 21:10

waqas


Getting both stdout and stderr (and also writing to stdin, not shown here) is easy peasy with my pstreams header, which defines iostream classes that work like popen:

#include <pstream.h> #include <string> #include <iostream>  int main() {   // run a process and create a streambuf that reads its stdout and stderr   redi::ipstream proc("./some_command", redi::pstreams::pstdout | redi::pstreams::pstderr);   std::string line;   // read child's stdout   while (std::getline(proc.out(), line))     std::cout << "stdout: " << line << '\n';   # if reading stdout stopped at EOF then reset the state:   if (proc.eof() && proc.fail())     proc.clear();   // read child's stderr   while (std::getline(proc.err(), line))     std::cout << "stderr: " << line << '\n'; }  
like image 21
Jonathan Wakely Avatar answered Oct 06 '22 21:10

Jonathan Wakely