我们从Jenkins buildserver开始使用Matlab。由于构建可能需要一些时间,因此在matlab运行时获取一些日志输出会很不错。有没有办法将文本打印到标准输出? disp,fprintf和java.lang.System.out.printline只写入matlab控制台,而不是标准输出。
Using a logfile 或管道无济于事,因为Jenkins只在构建步骤中从标准输出中读取。
如何在matlab运行时将log-statement写入标准输出?
修改 我们在Windows上运行Matlab 2010b
答案 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)
您可以使用日记模式。不确定它是否适合您的具体实施。
答案 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