2011-10-10 13 views
7

Stiamo avviando Matlab dal nostro Jenkins buildserver. Dato che la compilazione potrebbe richiedere del tempo, sarebbe bello ottenere alcuni log-output mentre Matlab è in esecuzione. C'è un modo per stampare il testo sullo standard output? disp, fprintf e java.lang.System.out.printline scrivono solo sulla console MATLAB, non sullo standard output.Scrittura delle istruzioni del registro sullo standard output con Matlab

Using a logfile o una pipe non è d'aiuto, poiché Jenkins legge solo dallo standard output durante una fase di costruzione.

Come possiamo scrivere le dichiarazioni di registro sullo standard output mentre Matlab è in esecuzione?

EDIT: Siamo in esecuzione Matlab 2010b su Windows

+0

Simile alla discussione qui: http://stackoverflow.com/questions/37830871/how-to-get-matlab-output-in-jenkins-console –

risposta

2

Non sembrano esserci buoni modi per fare questo dall'interno di MATLAB. Il modo più semplice che posso pensare di fare questo è usare uno script di shell. Potresti scrivere un piccolo script di shell che dovrebbe semplicemente stampare qualsiasi input su stdout e quindi chiamare lo script di shell da MATLAB usando i comandi unix (o system). Jenkins dovrebbe essere in grado di leggere l'output della riga di comando dello script e lavorare con quello.

+0

I pipe denominati in Windows non sono file ma più come socket. – ChrisK

4

seconda cosa si sta facendo con Matlab probabilmente si potrebbe lanciare nel riga di comando senza GUI. L'ho usato su un server e si comporta come uno script di shell e scrive sugli output degli standard.

Vedere startup options.

ho usato il seguente:

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

EDIT: dimenticato di dire molto importante piccolo dettaglio, inserire un comando exit alla fine del vostro MFILE o Matlab si bloccherà lì in attesa.

+0

AFAIK, MATLAB considera la finestra della console come lo standard output, quindi penso che questa sia la scelta migliore. – Nzbuu

+0

Se sei in grado di lavorare con l'istanza MATLAB basata su console senza gui, questa è una buona risposta. – eykanal

+3

Non funziona su Windows. Riceverò comunque una finestra di comando MATLAB. http://www.mathworks.de/help/techdoc/ref/matlabwindows.html – ChrisK

1

ho trovato un modo per fare questo e sto anche facendo per l'interfaccia Jenkins Matlab su Windows.

L'idea di base è che verrà utilizzato il comando diario, ma poi tail -f del file, ma è necessario un modo intelligente per uccidere il comando tail se si aprono più istanze MATLAB perché ci saranno conflitti di nomi. Quindi il metodo che sto usando è il nome del file log.txt dove il PID utilizzato è il PID di MATLAB che sta usando quando si apre.

Esiste una funzionalità non documentata in MATLAB che consente di ottenere il PID. Così ora, sia il tuo file batch che MATLAB conoscono il PID senza dover leggere/scrivere su un file di testo casuale che diventa confuso quando si eseguono più lavori. Quindi il PID lo usi come identificativo univoco.Il PID di "tail -f" viene anche utilizzato da MATLAB per eliminare tail -f per far morire il file batch e viene trovato da MATLAB utilizzando i dettagli della riga di comando associati al richiamo del processo poiché utilizza nuovamente il nome del file di registro PID univoco.

Questo utilizza alcuni comandi wmic e richiede Windows Vista/7 o successivo. Con XP probabilmente dovrai lavorare di più per ottenere l'ID del processo, ma dovrebbe essere ancora possibile.

Ecco cosa fare:

1) Ottenere awk GNU per le finestre: http://gnuwin32.sourceforge.net/packages/gawk.htm

2) Ottenere tail.exe da Windows Resource Kit: http://www.microsoft.com/en-us/download/details.aspx?id=17657

3) Assicurarsi che la coda e awk sono nel tuo percorso (il kit di windows resourece non penso li metta automaticamente nel percorso)

3) Creare un file batch chiamato matlabrun.bat come segue, (nota: è necessario il @echo off, anche il l'intero comando è piuttosto lungo, scorrere verso destra ..)

@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) Creare un altro file batch denominato run.bat con:

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) Il file run.bat eseguirà matlabrun.bat e dal -wait non viene passato, matlab tornerà immediatamente alla riga di comando ed eseguirà il comando tail -f. Ciò bloccherà il completamento del file batch fino a quando non lo ucciderai. matlabrun.bat restituisce il PID di matlab.

6) Un'altra nota importante: poiché si utilizza "wmic process create" che fornirà un PID che MATLAB sta utilizzando, ma verrà impostato automaticamente su una directory di lavoro di c: \ windows \ system32. Ecco perché passo la directory di lavoro a matlab. Anche wmic process create è un po 'particolare su quali parametri inserire nella stringa di comando per matlab da eseguire. Quindi sembra avere un problema con l'utilizzo di virgole nella stringa di comando. Quindi suggerisco di non usare quelli, o capire come sfuggirli (potrebbe essere che ^, funziona, ma ho comunque rimosso le mie virgole comunque nel mio comando run matlab).

6) Il file "test_run.m" contiene il seguente codice per scrivere nel file di registro corretto e per eliminare l'istanza coda -f corretta.

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) si avvia facendo run.bat. Andrà ed eseguirà MATLAB, quindi inizierà a tailing dell'output mentre MATLAB verrà eseguito in tempo reale. Al termine, cancellerà il file di registro.

8) La mia struttura di directory/file sono in questi luoghi (sto usando win7 64bit):

c: \ Jenkins \ test \ tail.exe workspace \

c: \ Jenkins \ spazio di lavoro \ test \ awk.exe

c: \ Jenkins \ workspace \ test \ matlabrun.bat

c: \ Jenkins \ workspace \ test \ run.bat

c: \ mATLAB \ lavori \ test_run .m

c: \ MATLAB \ bin \ win64 \ matlab.exe

Se si utilizza MATLAB a 32 bit, il punto alla directory win32.Per ottenere il PID corretto, è necessario specificare l'attuale binario matlab.exe nella directory win32 o win64.

0

Oppure provare a utilizzare l'opzione '-logfile' in MATLAB.

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

Io preferisco usare bash (Esegui shell) a Jenkins, allora si può coda del log-file mentre MATLAB è in esecuzione.

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

È possibile eseguire questa operazione puntando l'opzione -logfile sul file di registro Jenkins. Qualcosa di simile a quanto segue:

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

Sembra che la combinazione di -wait e -log (non -logfile) cloni l'output finestra di comando per stdout della console genitore, ma solose si chiama l'eseguibile MATLAB in [ MATLABROOT] \ bin, non [MATLABROOT] \ bin \ win64 (la sottodirectory per l'arco corrente).

testato su Windows con R2015b e R2016b:

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

NON

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

Ricordatevi di porre exit/quit nello script se si esegue con -r.

L'unico problema è che non riesco a trovare alcuna documentazione per l'opzione -log! Meh.

+0

great1 ottima scoperta, perché non è documentato! L'ho appena provato in R2017a e funziona benissimo. In effetti puoi usarlo in modalità interattiva. Quindi se avvii MATLAB con 'matlab.exe -wait -log' e crei un file MEX che usa' std :: cout', allora puoi vedere il suo output nel terminale (che non appare nel MATLAB finestra di comando). – Amro

Problemi correlati