使用Matlab将日志语句写入标准输出

时间:2011-10-10 14:59:44

标签: matlab command-line batch-file

我们从Jenkins buildserver开始使用Matlab。由于构建可能需要一些时间,因此在matlab运行时获取一些日志输出会很不错。有没有办法将文本打印到标准输出? disp,fprintf和java.lang.System.out.printline只写入matlab控制台,而不是标准输出。

Using a logfile 或管道无济于事,因为Jenkins只在构建步骤中从标准输出中读取。

如何在matlab运行时将log-statement写入标准输出?

修改 我们在Windows上运行Matlab 2010b

8 个答案:

答案 0 :(得分:4)

根据你在使用Matlab做的事情,你可以在没有GUI的命令行中启动它。我在服务器上使用它,它的行为非常像shell脚本,并写入标准输出。

请参阅startup options

我使用了以下内容:

/path/to/matlab -nojvm -nodisplay -nosplash -nodesktop -r /path/to/mfile

编辑:忘了提一个非常重要的小细节,在你的mfile末尾放一个exit命令,否则Matlab会在那里等待。

答案 1 :(得分:2)

在MATLAB中似乎没有任何好方法可以做到这一点。我能想到的最简单的方法是使用shell脚本。您可以编写一个小的shell脚本,只需将任何输入打印到stdout,然后使用unix(或system)命令从matlab中调用该shell脚本。 Jenkins应该能够读取脚本的命令行输出并使用它。

答案 2 :(得分:2)

似乎-wait -log(不是-logfile的组合将命令窗口输出克隆到父控制台的标准输出,但如果你在[MATLABROOT] \ bin中调用MATLAB可执行文件,而不是[MATLABROOT] \ bin \ win64(当前arch的子目录),

使用R2015b和R2016b在Windows上测试:

C:\MATLAB\bin\matlab.exe -wait -log

不会

C:\MATLAB\win64\bin\matlab.exe -wait -log

如果您使用exit运行,请务必在脚本中添加quit / -r

唯一的麻烦是,我似乎无法找到-log选项的任何文档! MEH。

答案 3 :(得分:1)

我找到了一种方法来做到这一点,我也在为Windows上的Jenkins Matlab界面做这件事。

基本思想是你将使用diary命令,但是然后tail -f文件,但如果打开多个matlab实例,你需要一种聪明的方法来终止tail命令,因为会有名称冲突。所以我使用的方法是命名文件log.txt,其中使用的PID是MATLAB在打开时使用的PID。

MATLAB中有一个未记录的功能,允许您获取其PID。所以现在,你的批处理文件和MATLAB都知道PID,而不必读/写随机文本文件,这个文件在执行多个作业时会变得混乱。所以你使用它作为唯一标识符的PID。 MATLAB还使用“tail -f”的PID来终止tail -f以使批处理文件死亡,并且由MATLAB使用与进程调用相关联的命令行详细信息找到它,因为它再次使用唯一的PID日志文件名。 / p>

这使用了一些wmic命令,需要Windows Vista / 7或更高版本。使用XP,您可能需要更加努力地获取进程ID,但仍然可以使用。

以下是该怎么做:

1)获取windows的gnu awk:http://gnuwin32.sourceforge.net/packages/gawk.htm

2)从Windows资源工具包中获取tail.exe:http://www.microsoft.com/en-us/download/details.aspx?id=17657

3)确保你的路径中有尾部和awk(我认为不会自动将它们放入路径中的窗口resourece工具包)

3)创建一个名为matlabrun.bat的批处理文件,如下所示(注意:你需要关闭@echo,整个命令也很长,向右滚动..)

@echo off
wmic process call create "c:\matlab\bin\win64\matlab.exe -r \"cd('c:\jenkins\workspace\test'); workdir=pwd; outpath=[pwd '\output'] ; try; run('C:\MATLAB\work\test_run'); end; quit; \" "  | findstr ProcessId | awk "{print $3}" | awk -F";" "{ print $1 }"

4)使用:

创建另一个名为run.bat的批处理文件
for /f %%i in ('matlabrun.bat') do (

 echo MATLAB Log... > log%%i.txt

 tail -f log%%i.txt

 set logfilename=log%%i.txt

 goto next

)

:next

del /f %logfilename%

5)run.bat文件将执行matlabrun.bat,并且由于未传递-wait,matlab将立即返回命令行并执行tail -f命令。这将阻止批处理文件完成,直到你杀死它。 matlabrun.bat返回matlab的PID。

6)另一个重要的注意事项:因为您正在使用“wmic process create”,它将为您提供MATLAB正在使用的PID,但默认为c:\ windows \ system32的工作目录。这就是我将工作目录传递给matlab的原因。 wmic process create对于将哪些参数放入命令字符串以供matlab运行也有一点特别之处。因此,在命令字符串中使用逗号似乎有问题。所以我建议不要使用它们,或者弄清楚如何逃避它们(可能是^,有效,但我只是在matlab运行命令中删除了我的逗号)。

6)“test_run.m”文件包含以下代码,用于写入正确的日志文件并终止正确的tail -f实例。

matlabpid=feature('getpid');
filename=['log',num2str(matlabpid),'.txt'];
filenamefull=[workdir,'\',filename];

diary(filenamefull);
disp('Script starting...')


%%% put your code here %%%


disp('Script completed...');
diary off;

%%% FIND PID of tail.exe and kill it 
%%% by using the name of the log file in the process command line
[a,b]=dos(['wmic process get Commandline,ProcessId']);
C=textscan(b,'%s','delimiter','\n');C=C{1};
for jj=1:size(C,1),
    if strfind(C{jj},filename),
        D=textscan(C{jj},'%s');D=D{1};
        dos(['taskkill /f /pid ',D{4}]) %kills tail.exe which is the log watcher
        break
    end
end

7)你可以通过run.bat来启动它。它将执行matlab,然后在MATLAB实时运行时开始拖尾输出。然后完成后它将删除日志文件。

8)我的目录结构/文件位于这些位置(我使用的是win7 64bit):

C:\詹金斯\工作空间\测试\ tail.exe

C:\詹金斯\工作空间\测试\ awk.exe

C:\詹金斯\工作空间\测试\ matlabrun.bat

C:\詹金斯\工作空间\测试\的run.bat

C:\ MATLAB \工作\ test_run.m

C:\ MATLAB \ BIN \ Win64的\ matlab.exe

如果您使用的是32位matlab,请将其指向win32目录。要获得正确的PID,您需要在win32或win64目录中指定actualy matlab.exe二进制文件。

答案 4 :(得分:1)

您可以通过将-logfile选项指向Jenkins日志文件来执行此操作。如下所示:

"C:\path\to\matlab.exe" "-r" "functionToRun" "-logfile" "%JENKINS_HOME%\jobs\%JOB_NAME%\builds\%BUILD_NUMBER%\log" /wait

答案 5 :(得分:0)

您可以使用日记模式。不确定它是否适合您的具体实施。

http://www.mathworks.com/help/techdoc/ref/diary.html

答案 6 :(得分:0)

我没有找到真正的解决方案。 Mathworks创建了一些包装工具。但这只会在matlab退出后输出结果。执行期间不会获得任何输出。

http://www.mathworks.de/support/solutions/en/data/1-ACT3YN/index.html?product=ML&solution=1-ACT3YN

所以我没有真正的实时输出......

答案 7 :(得分:0)

或尝试使用' -logfile' matlab中的选项。

matlab.exe -nodisplay -nosplash -nodesktop -wait -logfile logfile.txt -r "try script.m ;catch err; disp(err.message); end ; exit"

我更喜欢在Jenkins中使用bash(Execute shell),然后你可以在matlab运行时拖尾日志文件。

matlab.exe <...> &
matpid=$!
tail -f logfile.txt &
tailpid=$!
wait $matpid
matexit=$?
kill $tailpid
sleep 1 # Just to make sure kill is done before Jenkins step ends and no zombie processes
exit $matexit