2012-04-10 11 views
10

Jeśli mam tej funkcji MATLABJak uzyskać wartość zwracaną z Matlab w skrypcie Bash?

function [result] = matlab_test(param1, param2) 

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

result = 'hello matlab'; 

I chcę, aby wywołać tę funkcję Matlab w bash skryptu jak

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

I chcę to wyjście

test 
matlab 
hello matlab 

Moje wymóg tutaj jest aby sprawdzić, czy możliwe jest użycie wartości zwracanej z Matlab w skrypcie basha, a także przekazanie jej przez potok. Chcę tylko, aby moja aplikacja była podzielona na małe komponenty (pliki) i komunikować się przez potoki/parametry. Krótko mówiąc, chcę zobaczyć, jak daleko mogę zawinąć skrypt Matlab w moim skrypcie basha, aby móc ustawić architekturę kodu.
Jeśli nie mogę tego zrobić, po prostu zbiorę część, której potrzebuję wartości zwracanej z MATLAB do skryptu matlab.

+0

Edytowałem swoją odpowiedź, aby spróbować odpowiedzieć na zmienione pytanie. – Sevenless

+0

W przypadku, gdy zwracana wartość jest małą liczbą całkowitą, prostym rozwiązaniem jest zwrócenie jej jako kodu wyjścia procesu Matlaba przy użyciu opcji ['exit (code)'] (http://au.mathworks.com/help/matlab/ ref/exit.html). Nie zapomnij o argumentach polecenia '-wait' (http://au.mathworks.com/help/matlab/ref/matlabwindows.html) na' matlab' przy próbie tego w systemie Windows. –

Odpowiedz

6

Zadajesz dwa pytania. Odpowiem na oba pytania, w tym na pytanie, dlaczego drugi może być niemożliwy w zależności od systemu operacyjnego (a na pewno niemożliwy w moim), a następnie proponuję obejście problemu zależne od tego rozwiązania.

Po pierwsze, używam takiego skryptu, aby zmusić Matlaba do interakcji z powłoką.

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

daje wyjście:

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

więc wyraźnie dwie wersje Ustawianie zmiennych środowiskowych nie działa. To prowadzi nas do twojego drugiego pytania.

Powodem niepowodzenia "echo" jest to, że zarówno system, jak i setenv tworzą powłoki zamknięte po zamknięciu Matlaba. Oznacza to, że Matlab nie może ustawić zmiennych środowiskowych poza powłoką, która go nazwała.

Istnieje obejście tego problemu dla systemów Windows omówione in this posting, który używa narzędzia firmy Microsoft. Wymieniono również here.

Nie wierzę, że istnieje obejście dla systemów * nix do ustawiania zmiennych środowiskowych z poziomu programu Matlab.

Oto metoda na zrobienie czegoś podobnego do opisanego.

Zakładam, że użycie echa nie jest tym, co faktycznie chcesz zrobić. Raczej zgaduję, że chciałbyś użyć wyjścia łańcuchowego zapisanego w zmiennej środowiskowej do użycia w dalszej pracy z komendami lub skryptami w powłoce. Jednym z możliwych Rozwiązaniem byłoby następujące:

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

Nadanie wyjściowa: [XXXXXX @ Compute-0-138 ~] $ ./stack_ex_3 Test Matlab Ostrzeżenie: Nie znaleziono system okienny. opcji wcześniejszej Java MWT 'ignorowane

      < 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 

To pokazuje, że komenda echo $temp1 oceniano w podpowłoce stworzonej przez setenv i temp1 posiada wartość przypisaną do niego. Wynik tego połączenia do powłoki jest teraz przechowywany w b (a zawiera 0 oznaczające powodzenie). Można sobie wyobrazić, że możesz przekazać całość tego, co chcesz zrobić w powłoce za pomocą polecenia systemowego, tak aby działała w podpowłoce. Musimy jednak poznać więcej szczegółów na temat twojego problemu, aby udzielić pełnej oceny tego podejścia.

zmiany i nawiązanie **********************

najbliższa rzecz do owijania Matlab i bash, że mogę myśleć jest następujący trik . Można rura wyjście ze skryptu Matlab do myresult.out z następujących czynności:

#!/bin/sh 

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

można grep linię grepMe z myresult.out, rura do sed, i wybrać tylko część linii wyjściowej trzeba, to rura że w pozostałej części skryptu. To jest tak blisko, jak myślę, że możesz dostać się do tego, co próbujesz zrobić.

+0

Proszę zobaczyć aktualizację w moim pytaniu dla bardziej objaśnienia mojego wymagania. Twoja odpowiedź jest dobra, ale potrzebuję bardziej eleganckiego sposobu, aby wysłać tę wartość do skryptu bash. –

2

Są dwie rzeczy, które próbujesz zrobić tutaj. Po pierwsze: wyświetla dane wyjściowe programu Matlab w powłoce. Po drugie, przypisz zmienną w powłoce.

Kiedy próbowałem tego, stwierdziliśmy, że Matlab napisze całym stdout ze swoim komunikatem otwarcia, więc skończyło się robi:

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

a następnie wewnątrz Matlab, zastępując sprintf z:

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

To jest jedno z pierwszych wymagań (możesz po prostu napisać do zwykłego pliku, a następnie wysłać plik, ale musisz użyć do tego celu &&, więc nie zobaczysz wyjścia, dopóki program Matlab nie zostanie całkowicie ukończony .). Drugi problem - wykonanie "A = wyniku" w programie Matlab i możliwość "echa $ A" w powłoce - jest trudniejsze. Można zrobić coś takiego:

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

w Matlab:

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

ale ja naprawdę nie wiem jak dobrze byłoby to działa.

2

Myślałem o tym przez ostatnie kilka dni i pomyślałem o czymś. Możesz użyć jednego z klonów MATLAB jako #! interpreter skryptów. Mój wybór to w Octave, tak:

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

printf umieszcza wartość na standardowe wyjście i można rurę stamtąd.

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

Teraz Octave nie jest dokładnie taka sama jak MATLAB, ale jest blisko, może wystarczy dla Twoich potrzeb. Ma także tę zaletę, że jest wolny.

Powiązane problemy