MATLAB Spoken Here

Calling Shell Commands from MATLAB 41

Posted by Michael Katz,

I’ve written before about accessing Java from the Command Line, but you can also make calls into other systems from MATLAB. For example, you can access libraries written in C/C++ or Fortran, connect to .NET processes (on Windows), and make calls to a system shell. Today I will discuss the different ways you can run a system shell command:

  • system: The system function will execute a command in your OS shell and return the execution status (generally 0 for success and 1 for an error). For example:
    s = system('dir')
     Volume in drive H is mkatz 
     Volume Serial Number is 0702-7BA0 
     
     Directory of h:\www\blog\java 
     
    05/17/2010  09:22 AM    <DIR>          . 
    04/19/2010  08:27 AM    <DIR>          .. 
    07/02/2009  01:10 PM                51 parsedouble.m 
    05/17/2010  09:43 AM    <DIR>          wordpress_html 
    07/02/2009  03:49 PM                85 inmemex.m 
    07/02/2009  04:04 PM                31 tmp.m 
    07/08/2009  08:02 AM               154 swing.m 
    07/10/2009  09:39 AM               134 size_listen.m 
    08/17/2009  01:43 PM               593 m3m.m 
    04/26/2010  08:26 AM               146 heap_size.m 
    04/26/2010  08:29 AM                44 maxmem.m 
    05/17/2010  09:22 AM                17 system_commands.m 
                   9 File(s)          1,255 bytes 
                   3 Dir(s)   8,975,208,448 bytes free 
    
    s =
    
         0
    
    

    The nice thing about the system function is that it is platform independent, which means if you don’t care where your code will run and the command it will issue is the same, you can reuse this function. Note that system is platform-independent, but the system commands you run using this are likely to be very dependent on your OS. If you have platform-specific code, the isunix, ispc, ismac, and computer functions will allow you to programmatically determine what operating system the program is running on.

  • There’s also the !, or exclamation point operator. This is symbol is sometimes also known as “bang” or “hey there”, and it’s just a shorthand for the above mentioned system operation. The “!” operation is quick an easy, but can’t be used to take functional arguments. Because we Tab-complete filenames with system operations, a dirty trick to complete file paths from the command line is to stick a “!” at the start of the line, write out a normal MATLAB expression and then delete the “!” when you’re done.

With either of these functions, there are a few things to keep in mind. By default they will pause the MATLAB execution until the system command exits. If you just want to kick off a separate system process and have MATLAB continue, append an ampersand (“&”) to the end of the command. Also, if you want to capture the output of a system command as a string, wrap the call as an input to the evalc function:

s = evalc('system(''dir'')')
s =

 Volume in drive H is mkatz 
 Volume Serial Number is 0702-7BA0 
 
 Directory of h:\www\blog\java 
 
05/17/2010  09:22 AM    <DIR>          . 
04/19/2010  08:27 AM    <DIR>          .. 
07/02/2009  01:10 PM                51 parsedouble.m 
05/17/2010  10:03 AM    <DIR>          wordpress_html 
07/02/2009  03:49 PM                85 inmemex.m 
07/02/2009  04:04 PM                31 tmp.m 
07/08/2009  08:02 AM               154 swing.m 
07/10/2009  09:39 AM               134 size_listen.m 
08/17/2009  01:43 PM               593 m3m.m 
04/26/2010  08:26 AM               146 heap_size.m 
04/26/2010  08:29 AM                44 maxmem.m 
05/17/2010  10:03 AM                28 system_commands.m 
               9 File(s)          1,266 bytes 
               3 Dir(s)   8,975,208,448 bytes free 

There are also platform-specificthese system commands: dos and unix. However, these commands are exactly the same as system. If I had to guess, we’ve probably been keeping them around for compatibility reasons.

My personal favorite of all of these is winopen which is Windows-only, and it’s basically what you would get if you typed the input command in the Run box of the Start menu. I use this command all the time to open a path in an explorer window, like so:

winopen(pwd)

Matt Dunham at the Advanced MATLAB blog wrote a nice post awhile back about a whole range of systems that you can access from the MATLAB commands, and expands on some of the concepts presented here.

41 CommentsOldest to Newest

Why would you use evalc to capture the output?
Wouldn’t this do the same?
[status, result] = system(‘dir’);

I have run into some issues with running executables (.exe) from within Matlab using the system command, especially when the data from the executable is written to an output file that is going to be read into Matlab. It appears to be something with the timing in that when trying to read the output, the file is not complete. The only way I have found to remedy the issue is to put the system command in a while loop like this:

    count = 1;
    result = 0;
    while ~isempty(result) && count<=5
        [status, result] = system('MODTRAN.exe');
        count = count+1;
    end

Any guidance for a more elegant solution?

winopen(pwd)

Oh man, THANK YOU! I should have thought of this nice solution long ago. Live and learn.

@Eric,

That is quite possible in regard to file i/o. That’s a tough one. Is there something about the file you could poll for? Do you have to call the executable multiple times, or can just use PAUSE?

@Mike,
I suppose I could poll the file, but to me, that seemed even less elegant than what I chose to do. The reason I had to implement this way is that SOMETIMES it works on the first call. Typically the function containing this call is called in a loop and without the while loop, it fails at random points within the loop.

Pause works sometimes but I thought it was overkill since sometimes the pause is not needed.

Oh well. This seems to work but not as elegant as I like.

I wanted to make a linux alternative for

winopen

, using the code:

system(['xdg-open ' regexprep(folder, ' ', '\\ ')])

where folder is the path to the folder. xdg-open should open the folder in the default file browser.

regexprep

is used to replace white spaces with ‘\ ‘ to prevent errors. However, upon executing this command, I receive the following error:

nautilus: /home/nick/sys/os/glnx86/libstdc++.so.6: version `GLIBCXX_3.4.11' not found (required by /usr/lib/libexempi.so.3)

The same error arises when using the ‘nautilus’ command. Any idea how to solve this?

@NickS,

Is it a path or environment variable issue? You might have to set those before calling the nautilus command.

@Mike

I solved the problem. I just removed the dynamic link to libstdc++.so.6 and now it works just perfect. I am using Ubuntu Linux 10.04.

Why doesn’t the & show up in the documentation along with the list of special characters?

What is this nautilus command?

Is there any way to maintain continuity between shell calls (in UNIX?). I have some setup I need to do before the command I really want can be executed. The setup takes time, so I’d like to just do it once so I can then call my desired command over and over quickly.

As an example of what I mean though:

unix('setenv BOB abc;echo $BOB')

says ‘abc’, but

unix('setenv BOB abc')
unix('echo $BOB')

says BOB is undefined. It’s like it creates a new shell each time from scratch. Any solution?

@Chuck,
Each call to unix is going to be a separate shell. You can set your environment in an init file, like a .cshrc. Alternatively you can write a batch script that runs all the commands once.

Hi Mike

I have a little shortcut that launches a windows explorer in the current path, “pwd”. I’m on a Windows Vista x64 machine and the code i’m using is

system(['%SystemRoot%\explorer /e,',pwd,',select,',pwd,'''']);

The only catch is the command window becomes unresponsive until i kill the launched explorer window, even then i have to apply a few Ctrl-C’s to get things going sometimes. Any ideas how to make this system call work?
The good news is that it appears that the following code snippet seems to work fine:

p=java.io.File(pwd);
jd=java.awt.Desktop.getDesktop;
jd.browse(p.toURI)

Boris

@Boris,

I haven’t tried winopen(pwd) on Vista, but I assume it should still work? As for returning control back to MATLAB, just tack on a “ &” at the end of the system command.

@Mike

Didnt even think of trying winopen(pwd), but that seems to work perfectly as well! So it looks like either winopen or the JAVA soln work fine. The problem i had with the “&” in the system call is that it launches a DOS window which i didnt want. Thanks mate.

On OSX, winopen is replaced by “open”

Gnome: gnome-open
KDE: kde-open

These commands are available for almost any desktop environment.

One problem with the system-command is if I have special characters in my filename. The shell will interpret *, ;, [, ], ‘, “, etc. Is there any alternative to system that calls a process without calling the shell, or a function that escapes all special shell characters so it is safe to pass to system?

@Gerrit, what environment are you in? My suggestion may be different for WinXP/Cygwin shell from one for Linux/bash….

Hi Mike,
For a project of mine, I need to open a file with windows media player (not mmplayer) and then once it starts playing, I need to do some other tasks in matlab.

I tried with the System() command but it does not return the control until it is finish playing.

Is there any way that I can work around this. Any help is much appreciated.

Hi Mike,
I am using system() to call python scripts and it has been working fine when running matlab in the GUI, and in -nodisplay mode. However I have recently encountered a situation where I receive an Assertion failed error:

Assertion failed: Forced Assertion at line 320 of file “bnterm/bang.cpp”.
pty[222]: tcsetattr [5] Input/output error

This error occurrs when I use python to open and run matlab as a subprocess, this error is repeatable and always fails on the use of a system() command. Do you have any suggestions why the system() command stops working in this situation?

Kind regards

Apologies for the double post,
I have actually just found a solution to my problem although still unsure why it fails in this situation.
To prevent the Assertion failure I now have to run the python script that calls the matlab file in the background (using &). Since making this change I have not received an assertion failure on several tests.

Cheers

Hi,

I am using an instance of Matlab as a slave by running the following short routine:
while 1 > 0
[status,result] = system(‘./DoTheWork.csh abc’)
run MFileMadeByDoTheWork
end

I would like to pass at least one parameter to DoTheWork.csh in the system() call but haven’t figured out how to do variable substitution, i.e. I want abc to to be something that is assigned a value in MFileMadeByDoTheWork . I’m sure there’s some simple and obvious syntax rule but can’t find it.

It would be very helpful if someone could provide me the proper assignment statement to use in the M-File,
e.g.: abc = 3
and the proper syntax to use in the system call to get it to pass the value of abc to the shell script. Thanks for your help and direction.

Don

I think this is what you are looking for:
arg = ‘abc';
[status,result] = system(sprintf(’./DoTheWork.csh %s’, arg) );

Or, if the argument should be a number:
arg = 3;
[status,result] = system(sprintf(’./DoTheWork.csh %f’, arg) );

Thanks very much. That’s what I need.

This allows me to take advantage of Matlab toolbox routines without having Matlab as the central element in my programming environment. By spawning a slave, I avoid the high cost of repeatedly starting Matlab. And using Matlab synchronously makes the programming very simple.

Thanks again – don

Hi,

I am using a Matlab GUI, in which system is called to execute an executable, tool.exe.

tool.exe will run but will wait for an input to continue the process. Otherwise it will stay there waiting for the input from user. If running tool.exe in cmd shell, it will display the instructions when it’s ready to take the external input so I know when to do that.

However, when running with system in Matlab GUI, it seems the shell with hang there without displaying the information for user to input. it seems the SYSTEM will only display the output when an executable finishes running. This seems to be my problem.

I cannot run tool.exe at background with “&” either, since to continue on the rest Matlab code, I will need the output from tool.exe as input to the rest code.

Could you help me out on this?

Thanks.

Is there a way to cancel a running system command?

I’m using ‘dos’ to run a windows batch file and I want some way to terminate the running of dos program from inside MATLAB.

@Mike,
Did you try Ctrl+C ?

@Jim,
I don’t have an easy answer. A lot of it depends on various threading issues involved. Is the DOS program interactive, or does it just need to run to generate output? If it’s the later, maybe you can pipe the output to a file and display that in MATLAB.

The console application I was trying to run always prompted for input, and it wasn’t obvious to me how to insert that input while running my Matlab script.

I found a way to do it, which might be useful to you, Person of the Future:

userinput = ‘yes';
output = evalc(sprintf(‘!echo %s | command_that_asks_areyousure’, userinput));

Running Matlab 7.8.0.347 (R2009a) on a Linux distribution, I realized that my .cshrc login file is executed each time a system command is called (using either ! or system.m).

Is Matlab launching a new shell every time a command is passed to the OS?

Thanks

@Eric M.

I doubt you’ll see this, but I have the exact same problem using MATLAB to run MODTRAN! Thanks for the solution.

-Pete

I just upgraded to Ubuntu 12.10, and upgraded Matlab in the process. I’m trying to call a fortran program (called “anapert”). It works fine from the bash shell (aka command line).

Here is the specific code:

>>>anapert=’/home/dan/path/to/anapert';
>>>system(anapert)
/home/dan/Research/Karlsruhe/Rolf_prog_2011_01_20/anapert/anapert: /usr/local/MATLAB/R2012b/sys/os/glnxa64/libgfortran.so.3: version `GFORTRAN_1.4′ not found (required by /usr/lib/liblapack.so.3gf)

This code worked fine when running Matlab 2011b on Ubuntu 10.10, but now gives the error listed above. Since the code will execute from the command line, I presume the trouble is with Matlab, but I can’t tell what.

I have libgfortran, libblas, and lapack installed.

Help?

Aurélien, I appreciate it, but it seems like Matlab already knows where to find libgfortran:

$ locate libgfortran
/usr/local/MATLAB/R2012b/sys/os/glnxa64/libgfortran.so.3
/usr/local/MATLAB/R2012b/sys/os/glnxa64/libgfortran.so.3.0.0

I also provided links (in that folder) to liblapack3 and libblas3

Any other suggestions?

How does matlab determine which shell to use for system commands? The above link is broken, and I can’t find any good documentation on the topic.

Also, when I try to run system commands from a matalb process running on our cluster, all I get is the error: “This account is currently not available.”

Hi there!

I have a question about the “&” symbol.
I have to run an optimization. Inside this optimisation, I call another program which is quite long to load. However, once it is loaded, it goes quite fast.

For now, in each loop of the optimization, it loads the program (with optimization parameters as entry parameters), run it, export the results and unload the program. The results are sent back to the optimizer [and it loops].

However, if I use the program in a windows command line, I can load the program, type parameters, run it, type new parameters, run it, and so on. then unload.

My question, is there anyway to keep an interaction between a program that runs background (using “&”) to interactively type the parameters without loading and unloading it numerous number of time (it can take up to a whole night to run this optimization when most of the time is spent openning and closing the program!). If “&” can’t be a solution, is there any other way that you think?

Thank :)

These postings are the author's and don't necessarily represent the opinions of MathWorks.