How : MATLAB script that can get arguments from Unix command-line - matlab

Just for the sake of concreteness, consider the following super-simple Python script, in a file called add_em:
#!/usr/bin/env python
# script name: add_em
from sys import argv
x = int(argv[1])
y = int(argv[2])
x_plus_y = x + y
print '%d' % x_plus_y
I can now run this script, and pass arguments to it, from the Unix command line, like this:
% python add_em 3 8
11
If I make the script executable, I don't even need to mention python on the command line:
% chmod +x add_em
% add_em 41 -29
12
Can someone show me how to write (and run) a MATLAB script so that it performs exactly like the script above does? In particular, it must be able to read its arguments from the Unix command line (as opposed to, e.g., the MATLAB GUI's "command line"), and print their numerical sum to standard output.
NOTE: this script need not be "stand-alone"; IOW, one may assume that MATLAB is locally installed, and even that one can mention matlab in the command line (analogously to the first form above, where the python interpreter is explicitly invoked on the command line).
Thanks!
PS: Needless to say, this script is the antithesis of "robust", but my aim was to produce a readily conveyed example.

You can have a MATLAB function doing what you want inside add_em.m
function add_em(x, y)
x_plus_y = x + y;
disp(x_plus_y);
exit;
and then call it from Unix command line using the -r switch. Example:
matlab -nodesktop -nojvm -nosplash -r "add_em(3, 8)"
The - options suppress desktop, java and splash so the script/function will be executed without additional overhead.
You can additionally suppress the MATLAB welcome/copyright message by redirecting output to a logfile (for any computations) or tailing, for example, the output in order to get something printed on terminal
matlab -nosplash -nodesktop -nojvm -r "add_em(3, 8)" | tail -n 3
Update: Just found out this post/answers with relevant info: suppress start message of Matlab

Related

How to send commands to command window programmatically in MATLAB?

In matlab I can change to another shell by the bang (!) Notation.
Example:
I enter a conda Environment in MATLAB by the following command:
!cmd '"%windir%\System32\cmd.exe" /K ""C:\Program Files\Anaconda3\Scripts\activate_<conda-env-name>.bat" "C:\Program Files\Anaconda3""'
My MATLAB Command window then Displays following:
(<conda-env-name>) U:\some_starting_path>
Now, is there a way to send commands to this newly entered shell in a programmatic way, so that that command is evaluated in that very shell's syntax and not as a MATLAB-command?
For example, how can I write code that will execute a Python command without needing to enter it manually into the command line?
Not using the ! command or system(). Those are "one and done" functions.
But you can use Java's java.lang.Process API from within Matlab to control and interact with an ongoing process.
function control_another_process
pb = java.lang.ProcessBuilder(["myCommand", "myArg1", "myArg2"]);
proc = pb.start; % now proc is a java.lang.Process object
stdin = proc.getOutputStream; % Here's how you send commands to the process
stdout = proc.getInputStream; % And here's how you get its output
stderr = proc.getErrorStream;
% ... now do stuff with the process ...
end
You can use this with a shell, with python, or any other command.
Here's a Matlab class that wraps up the Java code to make it convenient to work with in Matlab: https://github.com/apjanke/janklab/blob/master/Mcode/classes/%2Bjl/%2Butil/Process.m

Run MATLAB script on cmd without opening the GUI window or the icon [duplicate]

I am running a MATLAB script from the Windows command prompt:
"C:\Program Files\MATLAB\R2014B\bin\matlab" -nodisplay -nosplash -nodesktop -wait -r "test.m"
The test.m is simple:
function test
disp('Hello!');
The output is displayed in the Matlab Command Window. Is there any way how I can force output to the windows prompt?
Use the command line option -log when you call Matlab from the command line (or any other shell or batch (e.g. cmd or bat) script).
It isn't documented as of Matlab 2017b, but it works.
Side note: -nodisplay isn't supported in the Windows version of Matlab, but if you want to prevent it from displaying figures, use -noFigureWindows instead.
Since R2019b, there is a new command line option, -batch, which redirects the output to the command line and handles other stuff for batch processing. See the documentation for Windows.
matlab -batch "statement to run"
This starts MATLAB without the desktop or splash screen, logs all output to stdout and stderr, exits automatically when the statement completes, and provides an exit code reporting success or error.
I don't know of a way to do it in Windows to get Matlab to actually run in the DOS window which is what you would need for the display to be written in it. (FYI: You can in LINUX - but I assume you need to run in Windows).
For running in Matlab you have 2 alternatives that I can think of:
-logfile FILE on launch which will record all output to a FILE you specify - however how and when the file is written to disk is controlled by Matlab and I haven't tested to see - if your code doesn't do much it might only be written on Matlab exit.
diary FILE in your Matlab command, i.e. -r "diary FILE.TXT; test.m; diary OFF" - this is similar to above - but uses the diary function.
However you can get what you want if you can run your code compiled (I know thats a big if as you may not have the compiler - or if you regularly want to update test.m this is not the most efficient...
When you run a compiled code from a DOS prompt all the terminal messages are written to the DOS prompt. One thing I'd advise if this is suitable is to delete the "splash.png" file from your installation directory to avoid the splash screen displaying when you run from the DOS as its (probably) not needed.
I have found a solution at:
https://www.mathworks.com/matlabcentral/answers/91607-how-can-i-redirect-the-command-window-output-to-stdout-and-stderr-when-running-matlab-7-8-r2009a-i#answer_100958
I will replicate it here for convenience.
First I need to modify the matlab script to output to a text file:
function test
fid=fopen('output.txt','w');
fprintf(fid,'Hello!');
fclose(fid);
Then I should run the Matlab using a bat file with one additional command to display the contents of the output.txt:
"C:\Program Files\MATLAB\R2014B\bin\matlab" -nodisplay -nosplash -nodesktop -wait -r "test.m"
type output.txt
The type command will display the contents of 'output.txt' in the command window. So answer from #matlabgui was almost there. Thank you.
It is not a very elegant solution, but it works.

Force Matlab output to command line

I am running a MATLAB script from the Windows command prompt:
"C:\Program Files\MATLAB\R2014B\bin\matlab" -nodisplay -nosplash -nodesktop -wait -r "test.m"
The test.m is simple:
function test
disp('Hello!');
The output is displayed in the Matlab Command Window. Is there any way how I can force output to the windows prompt?
Use the command line option -log when you call Matlab from the command line (or any other shell or batch (e.g. cmd or bat) script).
It isn't documented as of Matlab 2017b, but it works.
Side note: -nodisplay isn't supported in the Windows version of Matlab, but if you want to prevent it from displaying figures, use -noFigureWindows instead.
Since R2019b, there is a new command line option, -batch, which redirects the output to the command line and handles other stuff for batch processing. See the documentation for Windows.
matlab -batch "statement to run"
This starts MATLAB without the desktop or splash screen, logs all output to stdout and stderr, exits automatically when the statement completes, and provides an exit code reporting success or error.
I don't know of a way to do it in Windows to get Matlab to actually run in the DOS window which is what you would need for the display to be written in it. (FYI: You can in LINUX - but I assume you need to run in Windows).
For running in Matlab you have 2 alternatives that I can think of:
-logfile FILE on launch which will record all output to a FILE you specify - however how and when the file is written to disk is controlled by Matlab and I haven't tested to see - if your code doesn't do much it might only be written on Matlab exit.
diary FILE in your Matlab command, i.e. -r "diary FILE.TXT; test.m; diary OFF" - this is similar to above - but uses the diary function.
However you can get what you want if you can run your code compiled (I know thats a big if as you may not have the compiler - or if you regularly want to update test.m this is not the most efficient...
When you run a compiled code from a DOS prompt all the terminal messages are written to the DOS prompt. One thing I'd advise if this is suitable is to delete the "splash.png" file from your installation directory to avoid the splash screen displaying when you run from the DOS as its (probably) not needed.
I have found a solution at:
https://www.mathworks.com/matlabcentral/answers/91607-how-can-i-redirect-the-command-window-output-to-stdout-and-stderr-when-running-matlab-7-8-r2009a-i#answer_100958
I will replicate it here for convenience.
First I need to modify the matlab script to output to a text file:
function test
fid=fopen('output.txt','w');
fprintf(fid,'Hello!');
fclose(fid);
Then I should run the Matlab using a bat file with one additional command to display the contents of the output.txt:
"C:\Program Files\MATLAB\R2014B\bin\matlab" -nodisplay -nosplash -nodesktop -wait -r "test.m"
type output.txt
The type command will display the contents of 'output.txt' in the command window. So answer from #matlabgui was almost there. Thank you.
It is not a very elegant solution, but it works.

How to make matlab block the shell in windows?

I use win7 and matlab2012a. I want to write a shell script to test my matlab scripts with different parameters. I use cygwin for this task. For example, alpha is the parameter and the matlab script is getall.m. The matlab script will read parameters from txt file 'param.txt'.
#!/bin/sh
# List=`seq 0.1 0.01 1`
List=`seq 0.1 0.1 0.2`
for alpha in $List
do
echo -ne "20\n61\n80\n1\n0.3\n${alpha}" > param.txt
matlab -nodesktop -r "getall;quit;" #time consuming
done
My problem is that script "getall.m" is time consuming, so I'd like to exec it one at a time. But I found that matlab command returns immediately. So the upper script will start a lot of matlab instances at the same time. I also tried the matlab command in cmd, but nothing changes. In ubuntu, matlab blocks the shell by default.
My question is how to make the matlab command to block the shell in windows?
There's a matlab -wait command line switch on Windows that will make it block.
http://www.mathworks.com/help/matlab/ref/matlabwindows.html
I don't know the "right" way to do this - but I do have a hack for you:
Make the matlab script create a file called "matlabDone" in the /tmp directory just before quitting; your shell script can go around a loop looking for this file. Once it exists, you know matlab is finished. Delete the file, and go around the loop again. Something like this:
List=`seq 0.1 0.1 0.2`
for alpha in $List
do
echo -ne "20\n61\n80\n1\n0.3\n${alpha}" > param.txt
matlab -nodesktop -r "getall;quit;" #time consuming
while [ ! -e /tmp/matlabDone ]
do
sleep 1
done
rm /tmp/matlabDone
done
Then make the last line of your matlab script create the file /tmp/matlabDone...
As I said - it's a hack...
PS I am not 100% sure what functions are available in cygwin. If you can't use sleep, I saw an interesting post suggesting that ping -n 2 127.0.0.1 > /dev/null (or equivalent ... depending on the version of ping you might need -c 2 -i 1 to get "one second per ping, count two") can be an alternative to sleep().

How can I stop MATLAB from returning until after a command-line script completes?

I see in the MATLAB help (matlab -h) that I can use the -r flag to specify an m-file to run. I notice when I do this, MATLAB seems to start the script, but immediately return. The script processes fine, but the main app has already returned.
Is there any way to get MATLAB to only return once the command is finished? If you're calling it from a separate program it seems like it's easier to wait on the process than to use a file or sockets to confirm completion.
To illustrate, here's a sample function waitHello.m:
function waitHello
disp('Waiting...');
pause(3); %pauses 3 seconds
disp('Hello World');
quit;
And I try to run this using:
matlab -nosplash -nodesktop -r waitHello
Quick answer:
matlab -wait -nosplash -nodesktop -r waitHello
In Matlab 7.1 (the version I have) there is an undocumented command line option -wait in matlab.bat. If it doesn't work for your version, you could probably add it in. Here's what I found. The command at the bottom that finally launches matlab is (line 153):
start "MATLAB" %START_WAIT% "%MATLAB_BIN_DIR%\%MATLAB_ARCH%\matlab" %MATLAB_ARGS%
The relevant syntax of the start command (see "help start" in cmd.exe) in this case is:
start ["window title"] [/wait] myprogram.exe args ...
A bit higher, among all of the documented command line options, I found (line 60):
) else if (%opt%) == (-wait) (
set START_WAIT=/wait
) else (
So specifying -wait should do what you want, as long as you're also exiting matlab from your script (otherwise it will wait for you to terminate it interactively).