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.
Related
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.
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.
I am trying to use Matlab to send commands to FWTools in order to project a bunch of .shp files.
I am able to start FWTools from Matlab but I cant figure out how to send it commands without my interaction.
So far FWTools starts and my matlab command window and acts like the FWTools shell. I type commands and it will run, but I want to be able to send them in my .m file. Once FWTools starts up, my script will not continue to the next line of code.
My code so far:
cmd = 'ogr2ogr -s_srs "EPSG:4326" -t_srs "EPSG:3006" out_sweref99tm.shp in_wgs84.shp';
system('C:\Windows\system32\cmd.exe \K "d:\FWTools2.4.7\setfw.bat" ')
sprintf('%s',cmd) % try to send cmd to matlab command window aka FWTools
I also tried to put the cmd into my system call but that returned an error since it appears that I am trying to call FWTools with a super long string afterwards :(
cmd = 'ogr2ogr -s_srs "EPSG:4326" -t_srs "EPSG:3006" out_sweref99tm.shp in_wgs84.shp';
system(['C:\Windows\system32\cmd.exe \K "d:\FWTools2.4.7\setfw.bat" ',cmd])
The reason I am using FWTools is that I am projecting from WGS84 to SWEREF99TM and (from my understanding) its not easy to get the final projection via Matlab's mapping toolbox. Please correct me if I am wrong as I would love to keep it to Matlab.
And if possible, I would like to stay in Matlab and not move to Python.
Thanks.
Norris
The call of C:\Windows\system32\cmd.exe is not necessary.
Try this:
cmd = 'ogr2ogr -s_srs "EPSG:4326" -t_srs "EPSG:3006" out_sweref99tm.shp in_wgs84.shp';
system(['d: && cd d:\FWTools2.4.7\ && setfw.bat ',cmd])
or if you actually need to pass your parameters after the first call and not with:
system(['d: && cd d:\FWTools2.4.7\ && setfw.bat && ',cmd])
Maybe you can post a screenshot of how it looks like when you do it manually.
requested explanation:
The && operator is implicating that the following command is executed "in the next line". It's like you press enter in the cmd window and then you have to type the next command.
For example cd d:\FWTools2.4.7\ does never work directly, as the default is usually "c:". So firstly have to type d: and in the next step you change to your folder cd d:\FWTools2.4.7\
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)
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