Sergey Ivanov
Sergey Ivanov

Reputation: 3929

Get command line arguments in matlab

This is probably too easy, but I cannot google the answer for this: how can I get command line arguments in matlab script.

I run matlab as matlab -nodisplay -r "run('script.m')" and I want to return all arguments as a list. Something similar to python sys.argv. How can I do this?

I'm using Linux Mint and MATLAB 2015a.

Upvotes: 7

Views: 3633

Answers (2)

Rafael Monteiro
Rafael Monteiro

Reputation: 4549

I came up with a simple function that works on both Windows and Linux (Ubuntu):

function args = GetCommandLineArgs()

if isunix
    fid = fopen(['/proc/' num2str(feature('getpid')) '/cmdline'], 'r');
    args = textscan(fid, '%s', 'Delimiter', char(0));
    fclose(fid);
else
    kernel32WasAlreadyLoaded = libisloaded('kernel32');
    if ~kernel32WasAlreadyLoaded
        temporaryHeaderName = [gettempfolder '\GetCommandLineA.h'];
        dlmwrite(temporaryHeaderName, 'char* __stdcall GetCommandLineA(void);', '');
        loadlibrary('kernel32', temporaryHeaderName);
        delete(temporaryHeaderName);
    end
    args = textscan(calllib('kernel32', 'GetCommandLineA'), '%q');
    if ~kernel32WasAlreadyLoaded
        unloadlibrary kernel32;
    end
end

args = args{1};

On your sample call, it would return this:

>> GetCommandLineArgs

args = 

    '/[path-to-matlab-home-folder]/'
    '-nodisplay'
    '-r'
    'run('script.m')'

It returns a cell array of strings, where the first string is the path to MATLAB home folder (on Linux) or the full path to MATLAB executable (on Windows) and the others are the program arguments (if any).

How it works:

  • On Linux: the function gets the current Matlab process ID using the feature function (be aware it's an undocumented feature). And reads the /proc/[PID]/cmdline file, which on Linux gives the command line arguments of any process. The values are separated by the null character \0, hence the textscan with delimiter = char(0).

  • On Windows: the function calls GetCommandLineA, which returns the command line arguments on a string. Then it uses textscan to split the arguments on individual strings. The GetCommandLineA function is called using MATLAB's calllib. It requires a header file. Since we only want to use one function, it creates the header file on the fly on the temporary folder and deletes it after it's no longer needed. Also the function takes care not to unload the library in case it was already loaded (for example, if the calling script already loads it for some other purpose).

Upvotes: 4

m.s.
m.s.

Reputation: 16324

I am not aware of a direction solution (like an inbuilt function). However, you can use one of the following workarounds:

1. method

This only works in Linux:

Create a file pid_wrapper.m with the following contents:

function [] = pid_wrapper( parent_pid )

[~, matlab_pid] = system(['pgrep -P' num2str(parent_pid)]);
matlab_pid = strtrim(matlab_pid);
[~, matlab_args] = system(['ps -h -ocommand ' num2str(matlab_pid)]);
matlab_args = strsplit(strtrim(matlab_args));
disp(matlab_args);

% call your script with the extracted arguments in matlab_args
% ...

end

Invoke MATLAB like this:

matlab -nodisplay -r "pid_wrapper($$)"

This will pass the process id of MATLAB's parent process (i.e. the shell which launches MATLAB) to wrapper. This can then be used to find out the child MATLAB process and its command line arguments which you then can access in matlab_args.

2. method

This method is OS independent and does not really find out the command line arguments, but since your goal is to pass additional parameters to a script, it might work for you.

Create a file vararg_wrapper.m with the following contents:

function [] = wrapper( varargin )

% all parameters can be accessed in varargin
for i=1:nargin
    disp(varargin{i});
end

% call your script with the supplied parameters 
% ...

end

Invoke MATLAB like this:

matlab -nodisplay -r "vararg_wrapper('first_param', 'second_param')"

This will pass {'first_param', 'second_param'} to vararg_wrapper which you can then forward to your script.

Upvotes: 3

Related Questions