2012-04-10 7 views
10

Se ho questa funzione MATLABCome ottenere il valore di ritorno da matlab in script bash?

function [result] = matlab_test(param1, param2) 

disp(sprintf('param1 : %s', param1)); 
disp(sprintf('param2 : %s', param2)); 

result = 'hello matlab'; 

E voglio chiamare questa funzione MATLAB in script bash come

matlab -nodesktop -nosplash -nodisplay -r "try, A=matlab_test('test','matlab'); end; quit" 
echo $A 

E voglio che questa uscita

test 
matlab 
hello matlab 

La mia esigenza è qui per scoprire se è possibile utilizzare il valore restituito da Matlab nel mio script bash e anche passarlo attraverso la pipeline. Voglio solo rendere la mia applicazione separata in piccoli componenti (file) e comunicare attraverso pipeline/params. In breve, voglio vedere fino a che punto posso avvolgere lo script Matlab nel mio script bash in modo da poter impostare la mia architettura di codice.
Se non riesco a farlo, aggiungerò semplicemente la parte che mi serve il valore restituito da matlab insieme in uno script matlab.

+0

Ho modificato la mia risposta per provare a rispondere alla domanda rivista. – Sevenless

+0

Nel caso in cui il valore restituito sia un numero intero piccolo, una soluzione semplice è restituirlo come codice di uscita del processo Matlab, utilizzando ['exit (code)'] (http://au.mathworks.com/help/matlab/ ref/exit.html) comando. Non dimenticare l'argomento della riga di comando ['-wait'] (http://au.mathworks.com/help/matlab/ref/matlabwindows.html) su' matlab' quando si prova su Windows. –

risposta

6

Stai facendo due domande. Risponderò a entrambi, compreso perché il secondo potrebbe essere impossibile a seconda del sistema operativo (e sicuramente impossibile per il mio), quindi offrire un suggerimento su una soluzione alternativa al problema.

Per prima cosa, uso uno script come questo quando faccio in modo che Matlab interagisca con una shell.

#!/bin/sh 

cat <<EOF | matlab -nodesktop -nosplash -nodisplay 
A=matlab_test('$1','$2'); 
system(['export temp1=' A]); %doesn't work 
setenv('temp2',A); %also doesn't work, I'll explain why below 
exit 
EOF 
echo $temp1 
echo $temp2 

dà uscita:

[[email protected] ~]$ ./stack_ex test matlab 
Warning: No window system found. Java option 'MWT' ignored 

          < M A T L A B (R) > 
        Copyright 1984-2010 The MathWorks, Inc. 
       Version 7.12.0.635 (R2011a) 64-bit (glnxa64) 
           March 18, 2011 


    To get started, type one of these: helpwin, helpdesk, or demo. 
    For product information, visit www.mathworks.com. 

>> param1 : test 
param2 : matlab 
>> >> >> 

Così chiaramente le due versioni delle variabili di ambiente non funziona. Questo ci porta alla tua seconda domanda.

Il motivo alla base dell'errore di "echo" è che sia system sia setenv creano shell che vengono chiuse quando Matlab viene chiuso. Vale a dire, Matlab non può impostare variabili d'ambiente al di fuori della shell che lo ha chiamato.

C'è un rimedio per questo per i sistemi Windows discusso in this posting, che utilizza uno strumento di Microsoft. Anche menzionato here.

Non credo ci sia una soluzione alternativa per i sistemi * nix per impostare le variabili di ambiente da Matlab.

Ecco un metodo per fare qualcosa di simile a quello che hai descritto.

Suppongo che l'uso dell'eco non sia ciò che si desidera effettivamente fare. Piuttosto, suppongo che ti piacerebbe utilizzare l'output di stringa memorizzato nella variabile di ambiente da utilizzare in ulteriori lavori con comandi o script nella shell. Una possibile soluzione potrebbe essere la seguente:

#!/bin/sh 

cat <<EOF | matlab -nodesktop -nosplash -nodisplay 
A=matlab_test('$1','$2'); 
setenv('temp1',A); %doesn't work 
[a b] = system(['echo ' '$' 'temp1']) 
exit 
EOF 

uscita Dare: [XXXXXX @ compute-0-138 ~] $ ./stack_ex_3 prova MATLAB Attenzione: Nessun sistema a finestre trovato. opzione Java 'MWT' ignorato

      < M A T L A B (R) > 
        Copyright 1984-2010 The MathWorks, Inc. 
       Version 7.12.0.635 (R2011a) 64-bit (glnxa64) 
           March 18, 2011 


    To get started, type one of these: helpwin, helpdesk, or demo. 
    For product information, visit www.mathworks.com. 

>> param1 : test 
param2 : matlab 
>> >> 
a = 

    0 


b = 

hello matlab 

Questo dimostra che il comando echo $temp1 è stata valutata nella subshell creato da setenv e temp1 detiene il valore assegnato ad esso. Il risultato di questa chiamata alla shell è ora memorizzato in b (a detiene 0 che indica il successo). È concepibile che tu possa passare l'intero di ciò che vorresti fare nella shell attraverso il comando di sistema, in modo che venga eseguito nella sottochiave. Dovremmo conoscere più specifiche del tuo problema per dare una valutazione completa di questo approccio.

modifiche e follow **********************

La cosa più vicina al confezionamento Matlab e bash che mi viene in mente è il seguente trucco . È possibile reindirizzare l'output dello script Matlab per myresult.out con il seguente:

#!/bin/sh 

cat <<EOF | matlab -nodesktop -nosplash -nodisplay /> myresult.out 
A=matlab_test('$1','$2'); 
disp(['grepMe ' A]) 
exit 
EOF 

È possibile grep la linea grepMe da myresult.out, tubo per sed, e selezionare solo la parte della linea di uscita è necessario, allora tubo che sul resto del tuo copione. È così vicino come penso che tu possa arrivare a quello che stai cercando di fare.

+0

Si prega di consultare l'aggiornamento nella mia domanda per ulteriori spiegazioni sul mio requisito. La tua risposta è carina, ma ho bisogno di un modo più elegante per inviare quel valore a bash script. –

2

Ci sono due cose che stai cercando di fare qui. Primo: mostra l'output di un programma Matlab in una shell. In secondo luogo, assegna una variabile nella shell.

Quando ho provato questo, ho scoperto che Matlab avrebbe scritto tutto stdout con il suo messaggio di apertura, così ho finito per fare:

mkfifo ~/matlab_output 
matlab ... > /dev/null & cat ~/matlab_output 

e poi all'interno di MATLAB, sostituendo sprintf con:

f = fopen('~/matlab_output', 'w'); 
fprintf(f, 'param1 : %s', param1); 
fclose(f); 

Questa è una soluzione al tuo primo requisito (potresti semplicemente scrivere su un file normale e poi catare il file in seguito, ma dovresti usare && per quello, quindi non vedresti l'output fino a quando Matlab non sarà completamente finito .). Il secondo problema che hai - fare "A = result" in MATLAB e essere in grado di "echo $ A" nella shell - è più difficile. Si potrebbe fare qualcosa di simile:

mkfifo ~/matlab_commands 
mkfifo ~/matlab_output 
matlab ... > /dev/null & cat ~/matlab_output & eval $(cat ~/matlab_commands) 

e in MATLAB:

f2 = fopen('~/matlab_commands', 'w'); 
fprintf(f2, 'A=%s', double2str(results)); 
fclose(f2); 

ma io non so davvero come bene questo avrebbe funzionato.

2

State pensando a questo negli ultimi giorni e avete semplicemente pensato a qualcosa. Puoi usare uno dei cloni MATLAB come un #! interprete di sceneggiatura. La mia scelta in questo è ottava, in questo modo:

#! /usr/bin/octave -qf 
A=matlab_test('test','matlab'); 
printf(A) 

printf mette il valore di A in STDOUT e si può pipe da lì.

[email protected][~]$ ./oshelltest 
param1 : test 
param2 : matlab 
hello matlab 
[email protected][~]$ ./oshelltest | grep hello 
hello matlab 

Ora Octave non è esattamente lo stesso di MATLAB, ma è vicino, forse abbastanza per le vostre esigenze. Ha anche il vantaggio di essere libero.

Problemi correlati