How do I execute a command and get the output of the command within C++ using POSIX?
#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.
How to execute a command and get return code stdout and stderr of command in C++
From the man-page of popen
:
The pclose() function waits for the associated process to terminate and returns the exit status of the command as returned by wait4(2).
So, calling pclose()
yourself (instead of using std::shared_ptr<>
's destructor-magic) will give you the return code of your process (or block if the process has not terminated).
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
auto pipe = popen(cmd, "r"); // get rid of shared_ptr
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe)) {
if (fgets(buffer.data(), 128, pipe) != nullptr)
result += buffer.data();
}
auto rc = pclose(pipe);
if (rc == EXIT_SUCCESS) { // == 0
} else if (rc == EXIT_FAILURE) { // EXIT_FAILURE is not used by all programs, maybe needs some adaptation.
}
return result;
}
Getting stderr and stdout with popen()
, I'm afraid you'd need to redirect the output of stderr to stdout from the command-line you're passing to popen() by adding 2>&1
. This has the inconvinience that both streams are unpredictably mixed.
If you really want to have two distinguished file-descriptors for stderr and stdout, one way to do it is to do the forking yourself and to duplicate the new processes stdout/stderr to two pipes which are accessible from the parent process. (see dup2()
and pipe()
). I could go into more detail here, but this is quite a tedious way of doing things and much care must be taken. And the internet is full of examples.
C++ system() function — How to collect the output of the issued command?
Are you looking for returned value (as in "exit status") of the executed command, or for its output (as in "what did it print")?
If the latter, use popen()
and pclose()
instead.
If the former, look at the return value from system()
(and use the information from the waitpid()
information to interpret it).
How can I execute terminal commands from a C program?
how to execute terminal commands from my C program
...
(I would like to get the output)
Look at popen
Example
#include <stdio.h>
int main(int argc, char ** argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <command>\n", *argv);
return -1;
}
FILE * fp = popen(argv[1], "r");
if (fp != 0) {
char s[64];
while (fgets(s, sizeof(s), fp) != NULL)
fputs(s, stdout);
pclose(fp);
}
return 0;
}
Compilation and executions:
bruno@bruno-XPS-8300:/tmp$ gcc -Wall o.c
bruno@bruno-XPS-8300:/tmp$ ./a.out date
samedi 11 avril 2020, 17:58:45 (UTC+0200)
bruno@bruno-XPS-8300:/tmp$ a.out "date | wc"
1 6 42
bruno@bruno-XPS-8300:/tmp$ ./a.out "cat o.c"
#include <stdio.h>
int main(int argc, char ** argv)
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <command>\n", *argv);
return -1;
}
FILE * fp = popen(argv[1], "r");
if (fp != 0) {
char s[64];
while (fgets(s, sizeof(s), fp) != NULL)
fputs(s, stdout);
pclose(fp);
}
return 0;
}
bruno@bruno-XPS-8300:/tmp$
How to store command output and exitcode from terminal in a variable
Assuming the code provided in the article is correct and does what it should do, it is already doing all you need. The exit code and output are returned from the exec
function.
You only have to use the returned CommandResult
and access its members:
int main() {
auto result = Command::exec("echo blablub");
std::cout << result.output << "\n":
std::cout << result.exitstatus << "\n";
}
How do I execute a command and get the output of the command within C++ using POSIX?
#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.
Related Topics
What Is the Most Effective Way For Float and Double Comparison
When and Why Will a Compiler Initialise Memory to 0Xcd, 0Xdd, etc. on Malloc/Free/New/Delete
What Is the Effect of Extern "C" in C++
Is It a Good Idea to Typedef Pointers
What Uses Are There For "Placement New"
What Are Rvalues, Lvalues, Xvalues, Glvalues, and Prvalues
Passing a 2D Array to a C++ Function
Segmentation Fault on Large Array Sizes
How to Tokenize a String in C++
Rule-Of-Three Becomes Rule-Of-Five With C++11
How Does the Comma Operator Work
What Are Forward Declarations in C++
What Is Meant by Resource Acquisition Is Initialization (Raii)
Why Do I Have to Access Template Base Class Members Through the This Pointer
What Are Aggregates and Pods and How/Why Are They Special
What Does the C++ Standard State the Size of Int, Long Type to Be