【问题标题】:How can I get MATLAB's system() or dos() to show the console output in real time?如何让 MATLAB 的 system() 或 dos() 实时显示控制台输出?
【发布时间】:2016-07-13 21:34:39
【问题描述】:

我有一个 MATLAB 脚本,它使用 system() 命令调用可执行文件(用 C++ 编写),如下所示:

exe_status = system('MySimulation.exe', arguments);

由于可执行文件可能需要很长时间才能运行(最多几个小时),因此我在其中包含了一个函数,用于估计剩余时间并将其输出到控制台。如果我在 MATLAB 之外运行可执行文件,Windows 控制台大致如下所示:

Simulation #B01 initiated...
Completion: 0.57%    Time remaining: 183 m 2 s

使用\r 字符,“完成”行每秒都会自我重写。这非常有效,让我知道什么时候回来分析数据。

很遗憾,从 MATLAB 控制台调用可执行文件不会产生相同的效果。 MATLAB 一直等到可执行文件终止,然后才显示任何控制台输出,从而使我的计时器没有实际意义。

我尝试了以下命令,但它们都有相同的行为:

exe_status = system('MySimulation.exe', arguments);
exe_status = system('MySimulation.exe', arguments, '-echo');
exe_status = dos('MySimulation.exe', arguments);
exe_status = dos('MySimulation.exe', arguments, '-echo');

除非我读错了,否则MATLAB documentation 似乎表明'-echo' 可用于在可执行文件仍在运行时回显命令输出,但它对我的特定程序没有影响。

【问题讨论】:

  • 如果您尝试system('ping google.com') 之类的方法,您会得到什么?您是否在 ping 测试结束时也获得了所有信息?如果这对您来说不是问题,您也许应该每次打印一个新行...
  • @obchardon 实际上我没有;它按顺序输出到控制台。据我所知,system('ping google.com') 的行为与 Windows 控制台中的ping google.com 完全相同。
  • 最后加&有用吗? exe_status = system('MySimulation.exe &');
  • 查看this 线程和this one。这有点 hacky,但可能会起作用。
  • 你需要第二个输出参数:[status,results] = system('comp', '-echo');

标签: c++ matlab console


【解决方案1】:

我很好奇,所以我尝试了一些东西。我尝试了一个 bash 脚本、一个 c 可执行文件和一个 python 脚本,它们都“实时”地在 Matlab 命令窗口中显示它们的输出,这是该问题所期望的行为。我无法重现问题中描述的情况。

所以我怀疑:

a) 无论您使用何种方法叠印同一行,都是问题所在。它可能不是使用\r,它可能与您在 C++ 可执行文件中使用的特定打印方法有关。我会尝试不使用叠印,而只需使用您能想到的最简单的打印语句在新行上打印状态。

或者,

b) 问题是特定于操作系统的。

为了完整起见,以下是我尝试的方法和结果(环境和打印语句)的详细信息:

  1. bash 脚本; echo ""
  2. 编译的c代码; printf("\n")
  3. python 2.7 脚本; print("".format() )
  4. os 内置 ping 程序(如 cmets 中所述)

我在 Matlab 中运行了这个,使用 system 命令,例如 system('./timer_out');。在所有情况下:

-如果没有第二个输出变量,则打印输出“实时”出现,无论使用'-echo'标志或尾随分号,例如:

tic; system('./timer_out'); toc

-如果给定输出变量,则打印输出被抑制,例如:

tic; [s,r]=system('./timer_out'); toc

-如果给定输出变量并且使用了'-echo'标志,打印输出会实时出现,例如:

tic; [s,r]=system('./timer_out','-echo'); toc

此行为符合文档。这些测试在 OS X 上使用 Matlab R2015b。

【讨论】:

  • 好吧,我可以排除套印是问题的根源。我禁用了更新“完成”行,它不影响 MATLAB 控制台行为。我在模拟之前和之后都有打印语句,运行大约需要一分钟。在启动可执行文件大约一分钟后,这两个语句仍然同时出现。不过,感谢您提供的详细信息-我将尝试复制您为缩小问题范围而采取的步骤。作为记录,我在 Windows 7 上运行。
【解决方案2】:

我想我最初的问题措辞过于字面 - 我通过修补 C++ 代码而不是 MATLAB 代码找到了解决方案。具体来说,我在控制台打印命令的末尾添加了std::endlstd::flush,如下所示:

std::cout << "Simulation #B01 initiated..." << std::endl;

我的猜测是,刷新流会提示 MATLAB“实时”(或多或少地)将流的内容显示到控制台,这是 Windows 控制台在我的特定计算机上和我的特定操作系统上不需要的东西等。我确信这里有关于可移植性的人生教训,但我对我正在做的事情的正确构图知之甚少。

作为旁注,我注意到MATLAB does not properly recognize the carriage return character \r in the console。为了防止我的可执行文件向控制台发送可能有数千行更新状态的垃圾邮件,我已经替换了旧的更新行函数

void time_remaining( ... ) {

    std::string completion_update = ( ... );

    std::cout << completion_update << "\r";

}

稍微复杂一点的

int time_remaining( string_length, ... ) {

    for(i = 0; i < string_length; i++) std::cout << "\b";

    std::string completion_update = ( ... );

    std::cout << completion_update << std::flush;

    string_length = completion_update.length();

    return string_length;

}

它依赖于退格字符\b 和字符串completion_update 上一次迭代的字符长度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-19
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多