tags:

views:

616

answers:

5

Hi,

I want to call matlab in bash non-interactively and use its result outside Matlab.

For example, I have a script test.m

rand(3,4)
quit

When I execute in bash

$ matlab -nosplash -nodesktop -nodisplay -r test
Warning: No window system found.  Java option 'MWT' ignored

                        < M A T L A B (R) >
              Copyright 1984-2008 The MathWorks, Inc.
                     Version 7.7.0.471 (R2008b)
                         September 17, 2008


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


ans =

0.8147    0.9134    0.2785    0.9649
0.9058    0.6324    0.5469    0.1576
0.1270    0.0975    0.9575    0.9706

Is it possible to suppress the start message of Matlab and only show the results also without "ans=".

Note I am asking a general question not just for this example.

Thanks and regards!

+2  A: 

I'd recommend saving the output to a file, and then reading in that file. This approach is slightly more complicated, but less fragile as formats change etc. It gives you much more control. You'll find plenty of scripts on the web to transform Matlab files to a different host language.

Example:

A = randn(3, 2);
save temp_output.mat A
# Later, read temp_output.mat in whichever language you desire.
Peter
+1  A: 

To suppress the display of ans =, you can use the DISP function:

disp(rand(3,4));

To suppress that first warning message, you can try adding in the option -nojvm to see if that helps.

To suppress everything else, you can try this solution from a MathWorks Newsgroup thread that addresses the same problem.

gnovice
-nojvm doesn't suppress the start-up message, i.e. "< M A T L A B (R) > ..."
Tim
@Tim: That was a mistype. I meant to suggest that it might help with the warning message. I'll fix that.
gnovice
+1  A: 

Calling MATLAB like this

matlab -nodisplay  <test.m &>matlab.output

will dump all of the startup messages and other displayed output into the matlab.output file (which can be named anything you want). If you then (following Peter's suggestion) have test.m save the result that you need to a file using

csvwrite('temp_output.txt',A)

or another appropriate output function you can then read in this file and proceed.

Ethan White
+4  A: 

Try using the -logfile command line option:

-logfile log         - Make a copy of any output to the command window
                       in file log. This includes all crash reports.

Then you can easily remove the first few lines using any way you want (sed for example). Example:

matlab.exe -nosplash -nodesktop -nojvm -logfile out.log -r 'rand(3,3), exit'
sed '1,5d' out.log

Also if you are running from a script where you need it to finish running before continuing, use the -wait option:

-wait      - MATLAB is started by a separate starter program
        which normally launches MATLAB and then immediately
        quits. Using the -wait option tells the starter
        program not to quit until MATLAB has terminated.
        This option is useful when you need to process the
        the results from MATLAB in a script. The call to
        MATLAB with this option will block the script from
        continuing until the results are generated.
Amro
More info on MATLAB startup options can be found here: http://www.mathworks.com/access/helpdesk/help/techdoc/index.html?/access/helpdesk/help/techdoc/matlab_env/f8-4994.html
Richie Cotton
+2  A: 

You could use the Unix command "tail +n" to remove the first n lines of output. That header looks like 10 lines, so this will strip it.

$ matlab -nosplash -nodesktop -nodisplay -r test | tail +10

This is a little fragile, though, since warnings (like that "no window system") will get stripped, and the header size will vary depending on what warnings happen (and those warnings are useful diagnostics). Also, that warning might be on STDERR instead of STDOUT, so "tail +9" might be what you need.

A more robust approach could be to modify the Matlab script to write to a separate file using fopen/fprintf/fclose. That way the header, warnings, errors, etc from Matlab will be separated from the formatted output you want. To get the "disp" output to go to that separate file handle, you can capture it using evalc. The outfile could be specified using an argument to test() in the -r message, and the $$ env variable (the bash process's PID) incorporated in the file name to prevent collisions in a multiprocess environment.

function test(ppid)
outfile = sprintf('outfile-%d.tmp', ppid);
fh = fopen(outfile, 'w');
myvar = rand(3,4);
str = evalc('disp(myvar)');
fprintf(fh, '%s', str);
fclose(fh);

To invoke it from bash, use this calling form. (May be minor syntax problems here; I don't have a Unix box to test on right now.)

% matlab -nosplash -nodisplay -r "test($$)" -logfile matlab-log-$$.tmp

Let's say your bash PID is 1234. Now you've got your output in outfile-1234.tmp and a Matlab log in matlab-log-1234.tmp. Stick them in /tmp if you don't want to be dependent on pwd. You could extend this to create multiple output files from a single matlab invocation, saving the startup costs if you need to compute multiple things.

Andrew Janke

related questions