Programming Blog

Jeremy Morgan

Mostly Coherent Ramblings of a Silicon Forest Software Developer

How to Capture the Output of a Linux Command in C++

By: Jeremy Morgan






Ok, I admit this is a pretty obscure one but this came up for a task at work today and I had forgotten exactly how to do this. I Googled around a bit and found a lot of answers I either didn’t understand completely or just seemed too complicated for what I was trying to accomplish. I had done this with the boost libraries before but I didn’t have them on this machine so I wanted a clean, stdlib type solution.

I dug around and found this snippet of code on my hard drive, and put something together to make it work. I didn’t write it, and I don’t remember where it came from so I can’t give credit for it, but it works like a charm:

(tested using G++ v. 4.4.4)

string GetStdoutFromCommand(string cmd) {

string data;
FILE * stream;
const int max_buffer = 256;
char buffer[max_buffer];
cmd.append(" 2>&1");

stream = popen(cmd.c_str(), "r");
if (stream) {
while (!feof(stream))
if (fgets(buffer, max_buffer, stream) != NULL) data.append(buffer);
pclose(stream);
}
return data;
}

As you can see, this is a function and you simply pass the command as a string to that function. It’s really easy to use. As a note, you can run system commands from within C using system. The problem with this is, the command is often run first, before any output commands and the function returns an integer indicating success or failure, but not the output of the string. The function above fixes that for you.

What it does is creates a buffer, opens up a read-only stream, runs the command and captures the output, stuffs it into the buffer and returns it as a string.

Here is how we put it to use:

int main (){

string ls = GetStdoutFromCommand("ls -la");

cout << "LS: " << ls << endl;

return 0;

}

Keep in mind that there is no real checking here, and you should test the outputs of the commands carefully. For instance, when I used it today I had a set of long commands where things were piped into grep and cut, etc and I found that if I got unexpected output it caused a problem which hung the executable. So you want to make sure and validate your input and output as you go along, don’t just go running a bunch of commands and working on the output without some good error checking.

Here is the full code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>

    using namespace std;

    string GetStdoutFromCommand(string cmd) {

    string data;
    FILE * stream;
    const int max_buffer = 256;
    char buffer[max_buffer];
    cmd.append(" 2>&1");

    stream = popen(cmd.c_str(), "r");
    if (stream) {
    while (!feof(stream))
    if (fgets(buffer, max_buffer, stream) != NULL) data.append(buffer);
    pclose(stream);
    }
    return data;
    }

    int main (){

    string ls = GetStdoutFromCommand("ls -la");

    cout << "LS: " << ls << endl;

    return 0;
    }

Like I said this a pretty obscure tutorial but I figured if I had this problem, others might as well so I thought I’d throw it up there. I hope it helps.

Happy Coding!


Do you want to be notified every time a new tutorial is posted?

If you want to see more tutorials like these subscribe to our spam free newsletter and get them instantly in your inbox or feed reader. If you want to get all my updates, subscribe to the main RSS feed here.

Comments