如果命令不打印结果,但进入某种交互模式,如何处理从C ++执行终端命令的输出?

时间:2014-11-14 10:10:33

标签: c++ c linux terminal

这个问题的灵感来自that one

我已经了解了如何从C或C ++代码执行utils。但是我们怎样才能得到一些命令的结果,这不仅仅是打印结果,而是进入一些交互模式并一直工作直到我们按下Ctrl+z或类似的东西?这样一个命令的例子是top

3 个答案:

答案 0 :(得分:0)

通常你不会。使用使其不具有交互性的选项启动命令。

从技术上讲,你可以从交互式终端界面获取信息,但是你会很难做到这一点,因为为了使界面像人一样,经常使用终端功能(termcaps,ncurses ..),它基本上可行通过输出特殊字符,所以你必须通过知道什么是期望来躲避这些字符,所以除非界面非常简单和静态(实际上甚至在这种情况下)它会很痛苦

答案 1 :(得分:0)

某些应用程序(例如" dialog")可以交互工作,并将其最终结果写入不同的输出流。在对话框的情况下,使用stderr(默认情况下)完成。如果您可以控制应用程序,则可以提供类似的操作,以便将信息传递给调用应用程序。

答案 2 :(得分:0)

您只需访问stdin,stdout和stderr。在fork之前根据需要创建管道并在fork之后调用execv或任何其他变体。

可以在这里找到一个例子:

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

还有一个常用的库来捕获子程序的输出,并对找到的项目的一些新操作做出反应。这个库最初是为tcl编写的,但也可以用于c和c ++。 http://expect.sourceforge.net/

在期望的lib周围有一些粘合代码,你的源代码可能如下所示:

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;

}
相关问题