Running a matlab program with arguments - matlab

I have a matlab file that takes in a file. I would like to run that program in the matlab shell, such as prog. I need to implement it so that it takes a number of arguments, such as "prog filename.txt 1 2 which would mean that i can use filename.txt and 1 2 as variables in my program.
Thank you!

In order to make a script accept arguments from the command line, you must first turn it into a function that will get the arguments you want, i.e if your script is named prog.m, put as the first line
function []=prog(arg1, arg2)
and add an end at the end (assuming that the file has only one function). It's very important that you call the function the same name as the file.
The next thing is that you need to make sure that the script file is located at the same place from where you call the script, or it's located at the Matlab working path, otherwise it'll not be able to recognize your script.
Finally, to execute the script you use
matlab -r "prog arg1 arg2"
which is equivalent to calling
prog(arg1,arg2)
from inside Matlab.
*- tested in Windows and Linux environments

Once your function is written in a separate file, as discussed by the other answer you can call it with a slightly more complicated setup to make it easier to catch errors etc.
There is useful advice in this thread about ensuring that Matlab doesn't launch the graphical interface and quits after finishing the script, and reports the error nicely if there is one.
For example:
matlab -nodisplay -nosplash -r "try, prog(1, 'file.txt'), catch me, fprintf('%s / %s\n',me.identifier,me.message), exit(1), end, exit(0)"
The script given to Matlab would read as follows if line spaces were added:
% Try running the script
try
prog(1, 'file.txt')
catch me
% On error, print error message and exit with failure
fprintf('%s / %s\n',me.identifier,me.message)
exit(1)
end
% Else, exit with success
exit(0)

Related

How to pass integers and strings from MATLAB to a PowerShell script?

I need to automate a test. The test itself is being written (by me) in MATLAB, has 5 stages, each stage ends with setting a value to an integer (uint16_t and uint8_t) and with a message. I have to pass these 5 integers and 5 strings to a PowerShell script because Jenkins can only run a PowerShell or Python script, but I'm not entirely sure how can I achieve that. I have never used PS or done any scripting, and there isn't much on the Internet on how to even run a MATLAB script with PowerShell. (Maybe I should check batch file scripts running MATLAB scripts.)
The only option I've found so far is writing into a (temporary) file with MATLAB, then reading from it (and deleting it), it could be a .txt file, or preferably a .csv file (although using csvwrite is not recommended by Mathworks), but this isn't very reliable. Can anyone suggest other methods to pass it more directly? The MATLAB file is not a function, but it can be made to be one that has these variables as outputs. Also, it's fine if the integers are cast to another integer type.
Like #TessellatingHeckler said the way is $results = matlab.exe yourscript.
Here is an example if you want more features when launch the tests like no display windows ,run in a batch mode or wait to the end of matlab execution.
runTestMatlab (){
result=$(matlab.exe -wait -nosplash -noFigureWindows -batch TestScript.m)
if [ $? -ne 0 ]; then
# Error with the Matlab run
echo $result
return 1
fi
echo "$result"
return 0
}
Then you can parse the result with awk or any other tool that you want.

Suppress output to stderr in matlab

I'm trying to suppress output from a code section in a script (namely the network initialization from a Caffe network). I've tried wrapping the corresponding bit of code in an evalc command
[suppressed_output, var_output] = evalc('someFunction(input)');
But this doesn't work. I've still got loads of lines of (non-error) output from the network initialization that are clogging my logs (amidst all the wanted output printed via fprintf('') in the script). I think this happens because the corresponding function is writing to STDERR (instead of STDOUT?) - the first line it prints is this warning:
WARNING: Logging before InitGoogleLogging() is written to STDERR
... and then hundreds of lines of what it is doing follow, e.g.:
I0215 15:01:51.840272 28620 upgrade_proto.cpp:66] Attempting to upgrade input file specified using deprecated input fields: tmp-def.prototxt
I0215 15:01:51.840360 28620 upgrade_proto.cpp:69] Successfully upgraded file specified using deprecated input fields.
...
Can I somehow suppress the output to STDERR (without messing with the function content)? Ideally only locally for this specific function, since I'd still like to get potential error messages.
In case it is relevant:
I call myScript via matlab command line and its output written to a log (mlexec.log) with tee:
matlab -nodesktop -nosplash -display :1 -r "try, myScript; catch e, disp(getReport(e)), end, quit force" 2>&1| tee mlexec.log
The problem here is, that in the matlab command line call, the output from STDERR is streamed to STDOUT by this "command": 2>&1. Since the .cpp file seems to stream its output to STDERR (according to the Warning), it will be forwarded to STDOUT and eventually the log.
Streaming STDERR (2) to Nirvana with 2>NUL or a different log file (e.g. 2>mlexec.stderr.log) solves the problem.
I wanted to post this in a comment but it said I had to have 50 reputation (I have 49 now...)
I think this is what you're looking for
EDIT/UPDATE:
One thing you can do is enclose a section of your code with warning on/off statements as follows:
warning('off','all')
%your code here
warning('on','all')
This should stop any warnings being output to stderr from that section. I personally do not recommend this, it's good to know what you're doing that the MATLAB runtime does not like.

Can script be configured to "exit on unhandled exception"?

Is there a simple way to configure a MATLAB script so that it exits upon encountering an unhandled exception (as opposed to reverting to the REPL)?
The reason for this is that when executing many runs of a script in (unsupervised) batch mode, any script that fails should exit immediately, and not hang indifinitely at (unattended) interactive prompt.
IMPORTANT CLARIFICATION: this script is meant to be executed from the Unix command line, not from the MATLAB interactive prompt. More specifically, the script is to be invoked with
matlab -nodesktop -nosplash -nojvm -r myscript.m
The script should always terminate MATLAB after it has executed all its code, and return a status code reflecting its success (0) or failure (some non-zero integer).
I'm looking for a global setting (or a command-line flag) that can be put into effect without affecting the rest of the code.
IOW, I'm looking for something analogous to the -e flag available in some Unix shells (e.g. bash, zsh), which has the effect of aborting a script immediately whenever the return status of a statement is non-zero (meaning that the statement failed).
I know that I can wrap the entire body of a script with a try-catch, like this (for example):
try
exit_code = 0;
%
% BODY OF SCRIPT
%
catch exc
fprintf(2, 'CAUGHT EXCEPTION:\n');
fprintf(2, '%s(%d): %s\n', exc.stack.file, exc.stack.line, exc.message);
exit_code = 1;
end
exit(exit_code);
...but, as I said above, I'm looking for something simple, with no, or at most minimal, impact on the code.
The default behavior when an unhandled exception occurs is that information about the error will be printed to the command window and control will return to the command window. You should not be getting an interactive prompt from the error unless you've explicitly enabled it with dbstop if error or there is a try/catch with a keyboard command in the catch block. To just get a plain error rather than an interactive prompt you can use dbclear if error to disable this behavior. I would check your startup files to make sure that you don't have dbstop if error in there.
A try/catch pair is really the only way that this can be done. What you can do is wrap your calls to your script with another file and put the call to your script within a try/catch block. This has the added benefit that you don't have to modify the script itself, just the "runner".
Also you won't want to use exit as that completely exits MATLAB.
your_script.m
disp('Doing my thing')
error('Throwing an error!')
calling_script.m
for k = 1:100
try
% Call your other script and hope for no errors!
your_script
catch ME
% Print information about the error and continue
fprintf(2, 'CAUGHT EXCEPTION:\n');
fprintf(2, '%s(%d): %s\n', ME.stack.file, ME.stack.line, ME.message);
end
end
Update
Based upon the clarification that you've provided that you want to run this from the Unix command line, you'll still want to use something similar with a try/catch statement combined with exit. Again, you could do this in an external file as shown above
calling_script.m
code = 0;
try
your_script
catch ME
fprintf(2, 'CAUGHT EXCEPTION:\n');
fprintf(2, '%s(%d): %s\n', ME.stack.file, ME.stack.line, ME.message);
code = 1;
end
exit(code)

run matlab and pass integer parameter from command line

I have a matlab function and I was able to run it from command line. Now I want to pass a parameter to the file from command line. The parameter is a integer. It seems when I pass from command line, it is always taken as a "char".
Here is how I run the command
matlab -nodesktop -nosplash -r "mycommand 3"
For example, if I have a function as
function [ ] = mycommand( a )
a = a+3;
disp(a)
end
it prints 54 instead of 6.
Is there a way to work around this? I don't want to check the type of the variable in my code.
Thanks
You need to execute the function as you would in the matlab interpreter:
matlab -nodesktop -nosplash -r "mycommand(3)"
(Notice the parenthesis around the 3)
MarkD gave a good answer. Although you mentioned you might be unhappy doing this (I'm sure for good reasons), another option would be to put a little extra code in to the beginning of your function, which would convert character inputs to numerical if the command were called via matlab -r:
if ischar(a)
a = str2num(a);
end

suppress start message of Matlab

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!
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.
More info on MATLAB startup options can be found here, or in the matlab executable reference pages: Windows/Unix
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.
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.
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.
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.