2

This question was inspired by that one.

I've understood how to execute utils from C or C++ code. But how can we get result from some command, that doesn't just printing the result, but enters some interactive mode and works until we press Ctrl+zor something like this? The example of such a command is top.

Community
  • 1
  • 1
VALOD9
  • 566
  • 2
  • 6
  • 22

3 Answers3

0

Usually you don't. You launch the command with options that makes them non interactive.

Technically you could get information from an interactive terminal interface, but you will have a hard time doing it, because in order for the interface to be human like, terminal capabilities are often used (termcaps, ncurses..) which basically works by outputting special characters, so you 'll have to dodge these characters by knowing what is expected when, so except if the interface is quite simple and static (actually even in this case) it's gonna be a pain.

Drax
  • 12,682
  • 7
  • 45
  • 85
  • So, the best way to get CPU utilization in my code is to call just `ps auxw` for example, get the result as string, parse it and sort by some criteria? – VALOD9 Nov 14 '14 at 10:43
0

Some applications (such as "dialog") can work interactively and write their final result to a different output stream. In the case of dialog, that is done using stderr (by default). If you have control over the application, you can provide for doing something like that, for passing back information to the calling application.

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). – Masked Man Feb 03 '15 at 11:01
  • There are several issues: I was pointing out that an interactive application can return useful information on a different output than that used to display. The initial example of top could have been answered by the -b option of top. The incomplete example for C++ needs clarification (for instance to show how stderr and stdout may be combined), and is not useful for the original question of C/C++. – Thomas Dickey Feb 05 '15 at 22:10
  • For C/C++, one might assume that the questioner knows about popen already, for instance. – Thomas Dickey Feb 05 '15 at 22:11
0

You simply can access stdin, stdout and stderr. Before you fork create the pipes as needed and fork and after that call execv or any other variant.

An example can be found here:

https://jineshkj.wordpress.com/2006/12/22/how-to-capture-stdin-stdout-and-stderr-of-child-program/

There is also a common used library to capture the output of a child program and react with some new actions on found items. This library was first written for tcl but can also be used for c and c++. http://expect.sourceforge.net/

With some glue code around the expect lib your source can look like this:

int main()
{   
    Tcl_Interp *interp = Tcl_CreateInterp();
    Expect_Init(interp);

    // read from file
    int lfd = open( "test.txt", O_RDONLY );
    int fd = exp_spawnfd(lfd);

    // or read from application
    int fd ? exp_spawn("top","top", (char*)0)));

    bool cont= true;

    Expections set1 =
    {   
        { exp_glob, "YYY", []( Expection& exp)->void { cout << "found: YYY" << endl; }},
        { exp_regexp, "XXX ([0-9]+)", []( Expection& exp)->void { cout << "found: XXX" << exp.GetResult(1) << endl;}},
        { exp_glob, "END", [&cont]( Expection& exp)->void { cout << "EOF" << endl; cont = false; }}
    };

    int cnt = 0;
    do
    {   
        cout << "Run " << cnt << endl;
        cnt++; 
        Expect ( fd, set1, 2 );
    } while ( cont );

    cout << "Finish" << endl;

    return 0;

}
Klaus
  • 24,205
  • 7
  • 58
  • 113