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.
Extracting dos command output in C
There's nothing like that in standard C, but usually, for compatibility with POSIX, compilers implement popen
(_popen
in VC++), which starts a command (as it would do with system
) and returns a FILE *
to the stream you asked for (you can ask for stdout if you want to read the output or stdin if you want to give some input to the program).
Once you have the FILE *
, you can read it with the usual fread
/fscanf
/..., like you would do on a regular file.
If you want to have both input and output redirection things start to get a bit more complicated, since Windows compilers usually do have something like POSIX pipe
, but it isn't perfectly compatible (mostly because the Windows process creation model is different).
In this case (and in any case where you need more control on the started process than the plain popen
gives you) I would simply go with the "real" way to perform IO redirection on Windows, i.e. with CreateProcess
and the appropriate options; see e.g. here.
How to redirect output from reading a bash script in c++?
Use popen
instead of system
.
The function popen
will give you a FILE *
you can read from.
FILE *script = popen("myfile.sh", "r");
while (fgets(line, LENGTH, script)) {
/* ... */
}
pclose(script);
Hooking output from the console
Have you tried looking at the popen function? This older question has some discussion:
Capturing stdout from a system() command optimally
how to read from stdout in C
Create an executable using:
#include <stdio.h>
int main()
{
char line[BUFSIZ];
while ( fgets(line, BUFSIZ, stdin) != NULL )
{
// Do something with the line of text
}
}
Then you can pipe the output of any program to it, read the contents line by line, do something with each line of text.
Related Topics
Why Use Std::Bind Over Lambdas in C++14
Explicit Specialization in Non-Namespace Scope
Catching Access Violation Exceptions
How to Open an Std::Fstream (Ofstream or Ifstream) With a Unicode Filename
Std::String to Float or Double
Static Member Initialization in a Class Template
No Default Constructor Exists For Class
Why No Default Move-Assignment/Move-Constructor
What Is the Partial Ordering Procedure in Template Deduction
How Does Generic Lambda Work in C++14
How to Take a Screenshot in a Windows Application
Unresolved External Symbol in Object Files
Why Does This Function Push Rax to the Stack as the First Operation
Catch Exception by Pointer in C++
What's "Wrong" With C++ Wchar_T and Wstrings? What Are Some Alternatives to Wide Characters