2012-04-10 19 views
10

Si tengo esta función MATLAB¿Cómo obtener el valor de retorno de matlab en el script bash?

function [result] = matlab_test(param1, param2) 

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

result = 'hello matlab'; 

Y quiero llamar a esta función MATLAB en escritura del golpe como

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

Y quiero que esta salida

test 
matlab 
hello matlab 

Mi requisito aquí es para ver si es posible usar el valor de retorno de Matlab en mi script bash y también para pasarlo a través de la canalización. Solo quiero separar mi aplicación en pequeños componentes (archivos) y comunicarme a través de pipeline/params. En resumen, quiero ver hasta qué punto puedo ajustar el script de Matlab en mi script bash para poder establecer la arquitectura de mi código.
Si no puedo hacer esto, simplemente agruparé la parte que necesito el valor de retorno de matlab en el script de matlab.

+0

He editado mi respuesta para tratar de responder a su pregunta revisada. – Sevenless

+0

En caso de que el valor de retorno sea un número entero pequeño, una solución simple es devolverlo como el código de salida del proceso de Matlab, utilizando ['exit (code)'] (http://au.mathworks.com/help/matlab/ ref/exit.html) comando. No olvide el argumento de la línea de comandos ['-wait'] (http://au.mathworks.com/help/matlab/ref/matlabwindows.html) para' matlab' cuando intente esto en Windows. –

Respuesta

6

Usted hace dos preguntas. Responderé a ambos, incluido el por qué el segundo podría ser imposible dependiendo de tu sistema operativo (y definitivamente imposible en el mío), y luego ofreceré una sugerencia sobre una solución alternativa dependiente del problema.

En primer lugar, uso un script como este para hacer que Matlab interactúe con un 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 

da salida:

[[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 
>> >> >> 

Así que claramente las dos versiones de las variables de entorno de ajuste no funciona. Esto nos lleva a su segunda pregunta.

La razón detrás de la falla al 'eco' es que tanto system como setenv crean depósitos que están cerrados cuando Matlab está cerrado. Es decir, Matlab no puede establecer variables de entorno fuera del shell que lo llamó.

Hay una solución para esto para los sistemas Windows que se tratan in this posting, que utiliza una herramienta de Microsoft. También se menciona here.

No creo que haya una solución para que los sistemas * nix establezcan variables de entorno desde dentro de Matlab.

Aquí hay un método para hacer algo similar a lo que describió.

Supongo que el uso del eco no es lo que realmente desea hacer. Más bien, supongo que le gustaría usar la salida de cadena almacenada en la variable de entorno para usarla en futuros trabajos con comandos o scripts en el shell. Una posible solución sería la siguiente:

#!/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 

salida de Dar: [XXXXXX @ compute-0-138 ~] $ ./stack_ex_3 MATLAB prueba Advertencia: No se encuentra el sistema de ventanas. opción de Java 'MWT' ignorado

      < 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 

Esto demuestra que el comando echo $temp1 se evaluó en el subnivel creado por setenv y Temp 1 contiene el valor asignado a la misma. El resultado de esta llamada al shell ahora se almacena en b (a mantiene 0 indicando éxito). Es concebible que pueda pasar todo lo que le gustaría hacer en el shell a través del comando del sistema, para que se ejecute en la subshell. Sin embargo, deberíamos conocer más detalles de su problema para ofrecer una evaluación completa de este enfoque.

ediciones y seguimiento **********************

Lo más parecido a envolver Matlab y bash que se me ocurre es el siguiente truco . Puede canalizar la salida de la secuencia de comandos de Matlab a myresult.out con lo siguiente:

#!/bin/sh 

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

Puede buscando la línea grepMe de myresult.out, tubería de sed, y seleccionar sólo la parte de la línea de salida que necesita, entonces tubería que en el resto de tu script Eso es lo más cerca que creo que puedes llegar a lo que estás tratando de hacer.

+0

Consulte la actualización en mi pregunta para obtener más información sobre mi requerimiento. Tu respuesta es buena, pero necesito una manera más elegante de enviar ese valor al script bash. –

2

Hay dos cosas que intenta hacer aquí. En primer lugar: muestra la salida de un programa de Matlab en un shell. En segundo lugar, asigne una variable en el shell.

Cuando probé esto, me encontré con que Matlab escribiría todo stdout con su mensaje de apertura, por lo que terminó haciendo:

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

y luego dentro de Matlab, en sustitución de sprintf con:

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

Esa es una solución a su primer requisito (podría simplemente escribir en un archivo normal y luego cat el archivo después, pero tendría que usar && para eso, por lo que no vería la salida hasta que Matlab estuviera completamente terminado .). El segundo problema que tienes - hacer "A = resultado" en matlab y poder "repetir $ A" en el shell - es más difícil. Se podría hacer algo como:

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

y en Matlab:

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

pero no se sabe muy bien lo bien que esto funcionaría.

2

He estado pensando en esto en los últimos días y he pensado en algo. ¡Puedes usar uno de los clones de MATLAB como #! intérprete de guiones Mi elección es en esta octava, así:

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

printf pone el valor de A en la salida estándar y se puede canalizar a partir de ahí.

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

Ahora Octave no es exactamente lo mismo que MATLAB, pero está cerca, tal vez lo suficiente para sus necesidades. También tiene la ventaja de ser gratis.

Cuestiones relacionadas