2011-10-10 41 views
7

我們從我們的Jenkins buildserver開始Matlab的。由於構建可能需要一些時間,因此在matlab運行時獲得一些日誌輸出會很好。有沒有辦法將文本打印到標準輸出? disp,fprintf和java.lang.System.out.printline只寫入matlab控制檯,而不是標準輸出。寫入日誌語句到標準輸出用Matlab

Using a logfile或管道不會幫助,因爲詹金斯只從標準輸出期間生成步驟中讀取。

我們如何寫日誌的語句到標準輸出,而MATLAB是運行?

編輯: 我們在Windows上運行

Matlab的2010年b
+0

與此處的討論類似:http://stackoverflow.com/questions/37830871/how-to-get-matlab-output-in-jenkins-console –

回答

2

似乎有不被任何好的辦法從內部MATLAB做到這一點。我能想到的最簡單的方法是使用shell腳本。你可以編寫一個小的shell腳本,它只需要將任何輸入打印到stdout,然後使用unix(或system)命令從matlab中調用該shell腳本。詹金斯應該能夠閱讀腳本的命令行輸出並使用它。

+0

Windows中的命名管道不是文件,但更像是套接字。 – ChrisK

4

根據所使用Matlab的做什麼,你也許可以啓動它的命令行無GUI。我在服務器上使用它,它的行爲非常像一個shell腳本並寫入標準輸出。

startup options

我用下面的:

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

編輯:忘記提到一個非常重要的小細節,在你的M文件的末尾放置exit命令或Matlab將掛在那裏等候。

+0

AFAIK,MATLAB認爲控制檯窗口是標準輸出,所以我認爲這是您的最佳選擇。 – Nzbuu

+0

如果您能夠使用基於gui-less控制檯的MATLAB實例,這是一個很好的答案。 – eykanal

+3

在Windows上不起作用。我仍然會得到一個matlab命令窗口。 http://www.mathworks.de/help/techdoc/ref/matlabwindows.html – ChrisK

1

我想出了一個辦法做到這一點,我也這樣做了詹金斯Matlab的界面窗口。

基本思想是,你將使用日記命令,但後來尾部的文件,但如果你打開多個matlab實例,因爲會有名稱衝突,你需要一個聰明的方式殺死tail命令。所以我使用的方法是命名文件log.txt,其中使用的PID是MATLAB打開時使用的PID。

有一個在MATLAB無證功能,可以讓你得到它的PID。所以,現在,批處理文件和MATLAB都知道PID,而無需讀取/寫入隨機文本文件,這會在執行多個作業時變得雜亂無章。所以你使用它作爲你的唯一標識符。MATLAB還使用MATLAB的tail -f來殺死尾部-f以使批處理文件死亡並且由MATLAB使用與進程調用相關聯的命令行細節找到,因爲它再次使用唯一PID日誌文件名。

這使用了一些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 (窗口資源工具包,我不認爲會自動將它們放在路徑中)

3)創建一個名爲matlabrun.bat的批處理文件,如下所示(注意:您需要@echo off,也可以整個命令是相當長,向右滾動..)

@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運行命令中刪除了我的逗號)。

6)「test_run.m」文件包含以下代碼以寫入正確的日誌文件並殺死正確的尾部-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 64位):

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目錄中指定實際的matlab.exe二進制文件。

0

或者嘗試在matlab中使用'-logfile'選項。

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 
1

您可以通過將-logfile選項指向Jenkins日誌文件來完成此操作。像下面這樣:

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

看來的-wait-log(不-logfile克隆命令窗口輸出到父控制檯的stdout,但只有組合,如果你調用在MATLAB可執行[ MATLABROOT] \ bin,而不是[MATLABROOT] \ bin \ win64(當前arch的子目錄)。

測試在Windows與R2015b和R2016b:

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

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

記得把一個exit/quit在你的腳本,如果你是-r運行。

唯一的麻煩是,我似乎無法找到-log選項的任何文檔!咩。

+0

➕1很棒的發現,爲什麼這沒有記錄!我只是在R2017a上試了一下,效果很好。實際上你可以在交互模式下使用它。所以如果你用'matlab.exe -wait -log'啓動MATLAB,並創建一個使用'std :: cout'的MEX文件,那麼你實際上可以在終端看到它的輸出(它不會在MATLAB中顯示命令窗口)。 – Amro