这个问题是受灵感that one。如何处理来自C++的终端命令执行的输出,如果命令不只是打印结果,而是进入一些交互模式?
我已经理解了如何从C或C++代码执行utils。但是我们怎样才能从一些命令中得到结果,这不仅仅是打印结果,而是进入一些交互模式并且一直运行,直到我们按下Ctrl+z
之类的东西?这种命令的例子是top
。
这个问题是受灵感that one。如何处理来自C++的终端命令执行的输出,如果命令不只是打印结果,而是进入一些交互模式?
我已经理解了如何从C或C++代码执行utils。但是我们怎样才能从一些命令中得到结果,这不仅仅是打印结果,而是进入一些交互模式并且一直运行,直到我们按下Ctrl+z
之类的东西?这种命令的例子是top
。
通常你不会。您可以使用使它们不交互的选项来启动命令。
从技术上讲,你可以从交互式终端界面获得信息,但是你会很难做到这一点,因为为了让界面变得像人一样,终端功能经常被使用(termcap,ncurses ..)通过输出特殊字符来工作,所以你必须在知道什么时候知道什么时候闪避这些角色,所以除非接口非常简单和静态(实际上即使在这种情况下),它也会是一种痛苦。
某些应用程序(如“对话框”)可交互工作,并将其最终结果写入不同的输出流。在对话框中,这是使用stderr完成的(默认情况下)。如果你对应用程序有控制权,你可以提供这样的功能,将信息传递给调用应用程序。
这并没有提供一个问题的答案。要批评或要求作者澄清,在他们的帖子下留下评论 - 你总是可以评论你自己的帖子,一旦你有足够的[声誉](http://stackoverflow.com/help/whats-reputation),你会能够[评论任何帖子](http://stackoverflow.com/help/privileges/comment)。 –
有几个问题:我指出,交互式应用程序可以在不同于用于显示的输出上返回有用的信息。 top的第一个例子可以通过top的-b选项来回答。 C++的不完整示例需要澄清(例如,要显示stderr和stdout如何组合),并且对于C/C++的原始问题没有用处。 –
对于C/C++,例如,可能会假设提问者已经知道popen。 –
您只需访问标准输入,标准输出和标准错误。在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;
}
因此,要获得CPU利用率在我的代码的最佳方式是打电话只是'PS auxw'例如,以字符串形式获得结果,解析它并按照某些标准排序? – VALOD9
@ VALOD9看起来像一个很好的方式去 – Drax