matlab-将dos命令输出显示为静态文本
我正在使用GUI调用终端命令。通过使用matlab-将dos命令输出显示为静态文本,matlab,batch-file,cmd,logfile,Matlab,Batch File,Cmd,Logfile,我正在使用GUI调用终端命令。通过使用dos(my_命令,'-echo')我可以在Matlab的命令窗口中获得命令输出。在我的GUI中,是否有任何方法可以在静态文本中复制该-echo 目前,使用my_命令,我将输出写入日志文件,并在处理完成后通过该日志文件更新静态文本的字符串,但我想要的是一个实时视图类似于命令窗口:实时逐行显示输出。谢谢 更新: @Hoki:另一个问题是:当控制台命令被执行时,如果我关闭GUI,那么Matlab将返回无法隐藏的错误,我如何冻结整个GUI直到命令完成 在执行dos
dos(my_命令,'-echo')
我可以在Matlab的命令窗口中获得命令输出。在我的GUI中,是否有任何方法可以在静态文本中复制该-echo
目前,使用my_命令
,我将输出写入日志
文件,并在处理完成后通过该日志
文件更新静态文本的字符串,但我想要的是一个实时视图
类似于命令窗口:实时逐行显示输出。谢谢
更新:
@Hoki:另一个问题是:当控制台命令被执行时,如果我关闭GUI,那么Matlab将返回无法隐藏的错误,我如何冻结整个GUI直到命令完成
在执行
dos
、unix
和系统期间,Matlab不提供本机方法来连续获取结果。尽管如此,仍有可能实现预期的行为
这是拟议的解决办法:
- 执行命令并将输出通过管道传输到文件
- 使用
&
字符继续执行Matlab代码
- 持续读取此文件的内容,并相应地更新GUI
- 引入第二个临时文件,指示停止更新过程的命令结束
代码如下:
多亏了这篇文章中的Yair Altman信息,我得到了一些有用的东西,但它涉及到黑客入侵Matlab Java基本对象(即命令窗口)
它涉及将侦听器附加到Matlab命令窗口。现在要小心,经常保存您的工作,并准备好多次终止Matlab进程,直到您将其正确。。。因为每次代码中出现错误时,都会陷入一种无限循环(错误/警告被发送到命令窗口,这会触发监听器,重新触发错误等等)。为了让下面的示例以稳定的方式工作,我不得不重新启动Matlab好几十次
这也是我只是暂时附加侦听器的原因。在发送dos
命令之前,我会在命令之后直接删除侦听器。你可以永久离开听众,也可以根据自己的需要进行调整,但记住上面的建议。还可以考虑命令窗口可以容纳大量字符,您可能不希望在所有文本框中都这样,因此必须管理从中获取的文本(如示例中的子集),并考虑是否要追加或简单刷新文本框中的文本。
下面的例子看起来很稳定,任何修改都有风险;-)
在注释I中请求后,添加了3个功能:
- 安。这是一个Matlab功能,允许在出现问题时采取最后的措施(一种“一网打尽”的机制)。强烈推荐使用未记录函数的此类程序
- 一个
myCloseRequestFcn
,它拦截窗口的关闭操作以删除侦听器并避免错误循环
- 一个
滚动到底部功能。此选项允许将文本框插入符号移动到文本末尾(=如果文本多于可见空间,则滚动到底部)
警告:最后一个功能可能需要一个单独的问题,并再次调用未记录的功能(因此兼容性永远无法保证)。要实现它,您需要在Matlab路径中提供该函数。如果不想下载外部组件,则删除/注释使用该组件的代码部分以及子功能滚动到底部
(忘记滚动文本框,在纯Matlab中无法实现)。或者,您可以通过查看帖子的编辑历史记录来选择代码的早期版本
但是在最后使用&
会使cmd窗口在后台保持打开状态,有什么办法可以避免吗?顺便说一句,我认为它应该是>temp_cmdlog&&echo>temp_cmdlog_done
@scmg中的一个&
来测试我使用OSX和系统
-命令的上述脚本。这就是我使用&&
的原因,因为其他版本不适合我。如果您确认它与单个和一起工作,我将更改它。我不知道如何关闭窗口的直接解决方案。我会先尝试将其混合到我的GUI中,然后回来。我确实尝试过,但仍然有一个问题:如果日志太长,如何设置最后的文本位置?@scmg。我不明白你的问题。你的意思是在命令窗口的末尾设置副本的开始位置吗?不,我的意思是:如果DOS中的输出太长,那么文本框总是显示日志的第一部分,我如何使它显示日志的最后一部分,就像我在讨论中更新的图片中一样?让我们来回答。这里提出了一个后续问题:
% create figure and uicontrol
fh = figure;
txtbox = uicontrol(fh,'Style','edit','Max',30,'Min',0,...
'HorizontalAlignment','left',...
'FontName','FixedWidth',...
'Position',[30 30 450 200]);
% store current path
path = cd;
% delete token to make sure the loop continues as expected
warnstate = warning('off','MATLAB:DELETE:FileNotFound');
delete(fullfile(path,'temp_cmdlog_done'));
warning(warnstate); % restore original warning state
% execute dos-command in background
cmd = 'ping -c 5 192.168.200.1';
dos([cmd,' > temp_cmdlog && echo > temp_cmdlog_done &']);
% refresh text in uicontrol until dos-command is done
while 1
out = fileread('temp_cmdlog');
set(txtbox,'String',out);
if exist(fullfile(path,'temp_cmdlog_done'),'file')
break;
end
pause(0.2); % adjust to suit your needs
end
% delete the temporary files
delete(fullfile(path,'temp_cmdlog'));
delete(fullfile(path,'temp_cmdlog_done'));
% indicate that process finished
set(txtbox,'ForegroundColor',[0,0.5,0]);
function h = gui_MirrorCmdWindow
%% // just to remove the listener in case something goes wrong
closeup = onCleanup(@() cleanup);
%% // create figure and uicontrol
h.f = figure;
h.txtOut = uicontrol(h.f,'Style','edit','Max',30,'Min',0,...
'HorizontalAlignment','left',...
'FontName','FixedWidth',...
'Units','Normalized',...
'Enable','On',...
'Position',[.05 .2 .9 .75]);
h.btnPing = uicontrol(h.f,'Style','Pushbutton',...
'String','Ping',...
'Units','Normalized',...
'Position',[.05 .05 .9 .1],...
'Callback',@btnPing_callback);
guidata(h.f,h)
%// intercept close request function to cleanup before close
set(gcf,'CloseRequestFcn',@myCloseRequestFcn)
%% // Get the handle of the Matlab control window
jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
jCmdWin = jDesktop.getClient('Command Window');
jTextArea = jCmdWin.getComponent(0).getViewport.getView;
%% // Get the handle of the jave edit box panel component
jtxtBox = findjobj(h.txtOut) ;
jTxtPane = jtxtBox.getComponent(0).getComponent(0) ;
%// Save these handles
setappdata( h.f , 'jTextArea', jTextArea ) ;
setappdata( h.f , 'jTxtPane', jTxtPane ) ;
function btnPing_callback(hobj,~)
h = guidata(hobj) ;
jTextArea = getappdata( h.f , 'jTextArea' ) ;
my_command = 'ping google.com -n 10' ;
startPos = jTextArea.getCaretPosition ;
set(jTextArea,'CaretUpdateCallback',{@commandWindowMirror,h.f,startPos}) ;
dos( my_command , '-echo' ) ;
pause(1) %// just to make sure we catch the last ECHO before we kill the callback
set(jTextArea,'CaretUpdateCallback',[]) ;
scroll_to_bottom(h.f)
function commandWindowMirror(~,~,hf,startPos)
h = guidata(hf) ;
jTextArea = getappdata( h.f , 'jTextArea' ) ;
%// retrieve the text since the start position
txtLength = jTextArea.getCaretPosition-startPos ;
if txtLength > 0 %// in case a smart bugger pulled a 'clc' between calls
cwText = char(jTextArea.getText(startPos-1,txtLength) ) ;
end
%// display it in the gui textbox
set( h.txtOut, 'String',cwText ) ;
scroll_to_bottom(h.f)
function scroll_to_bottom(hf)
%// place caret at the end of the texbox (=scroll to bottom)
jTxtPane = getappdata( hf , 'jTxtPane' ) ;
jTxtPane.setCaretPosition(jTxtPane.getDocument.getLength)
function myCloseRequestFcn(hobj,~)
cleanup ; %// make sure we remove the listener
delete(hobj) ; %// delete the figure
function cleanup
jDesktop = com.mathworks.mde.desk.MLDesktop.getInstance;
jCmdWin = jDesktop.getClient('Command Window');
jTextArea = jCmdWin.getComponent(0).getViewport.getView;
set(jTextArea,'CaretUpdateCallback',[]) ;