7

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.

10
  • Perhaps you can make an example of what exactly you want to get for those unfamiliar with the functionality you refer to in python? Commented Jun 12, 2015 at 12:20
  • Usually, arguments can be accepted or passed, not returned. What do you mean after the arguments here? Do you mean values of the function or you want to pass arguments inside? Commented Jun 12, 2015 at 12:21
  • If you want an example of how to call matlab from the command line, you can check out this question. Commented Jun 12, 2015 at 12:22
  • No, I just want from matlab access all command line arguments. In this example, I want to retrieve as a matrix [-nodisplay, -r, "run('script.m')"] Commented Jun 12, 2015 at 12:25
  • In fact, I want to pass some additional arguments at the end of command and I want to access those arguments from the script. Commented Jun 12, 2015 at 12:26

2 Answers 2

4

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).

Sign up to request clarification or add additional context in comments.

Comments

3

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.