11

How does one get a list of all defined environment variables in Matlab? I'm aware of getenv but you have to provide a name, and doc getenv offers no help in how to use it to retrieve items in any other way. I can't find any other relevant information online. Is this even possible?

I'm interested in a platform-independent answer (or at least Windows and Linux).

pattivacek
  • 5,617
  • 5
  • 48
  • 62

2 Answers2

10

You could use

system('env')

on linux/mac, and

system('set') % hope I remember correctly, no windows at hand

In both cases you'd have to parse the output though, as it comes in the format variable=<variable-value>.

pattivacek
  • 5,617
  • 5
  • 48
  • 62
sebastian
  • 9,526
  • 26
  • 54
  • I fixed the quotes and those work as expected. Honestly, having the variables listed with their values is probably a good thing, so this works fairly well. I'm still curious if there's a truly platform-independent way, but since environment variables are fairly platform-dependent, this might be as good as it gets. – pattivacek Nov 15 '13 at 17:20
  • 2
    You can also use `!env` in the MATLAB console window then. Just as additional hint. – Matthias W. Mar 02 '16 at 15:44
5

Below is a function that implements two ways to retrieve all environment variables (both methods are cross-platform):

  1. using Java capabilities in MATLAB
  2. using system-specific commands (as @sebastian suggested)

NOTE: As @Nzbuu explained in the comments, using Java's System.getenv() has a limitation in that it returns environment variables captured at the moment the MATLAB process starts. This means that any later changes made with setenv in the current session will not be reflected in the output of the Java method. The system-based method does not suffer from this.

getenvall.m

function [keys,vals] = getenvall(method)
    if nargin < 1, method = 'system'; end
    method = validatestring(method, {'java', 'system'});

    switch method
        case 'java'
            map = java.lang.System.getenv();  % returns a Java map
            keys = cell(map.keySet.toArray());
            vals = cell(map.values.toArray());
        case 'system'
            if ispc()
                %cmd = 'set "';  %HACK for hidden variables
                cmd = 'set';
            else
                cmd = 'env';
            end
            [~,out] = system(cmd);
            vars = regexp(strtrim(out), '^(.*)=(.*)$', ...
                'tokens', 'lineanchors', 'dotexceptnewline');
            vars = vertcat(vars{:});
            keys = vars(:,1);
            vals = vars(:,2);
    end

    % Windows environment variables are case-insensitive
    if ispc()
        keys = upper(keys);
    end

    % sort alphabetically
    [keys,ord] = sort(keys);
    vals = vals(ord);
end

Example:

% retrieve all environment variables and print them
[keys,vals] = getenvall();
cellfun(@(k,v) fprintf('%s=%s\n',k,v), keys, vals);

% for convenience, we can build a MATLAB map or a table
m = containers.Map(keys, vals);
t = table(keys, vals);

% access some variable by name
disp(m('OS'))   % similar to getenv('OS')
Community
  • 1
  • 1
Amro
  • 123,847
  • 25
  • 243
  • 454
  • +1 Like this one - I'd use this version to be honest. Surely should also be much faster - in case one needs to get them more than one time. – sebastian Nov 16 '13 at 17:50
  • 1
    Yeah, this version is cleaner and presumably more platform-independent. I always forget about Java tricks in Matlab! – pattivacek Nov 18 '13 at 14:58
  • 1
    The Java one actually gives different results that don't match `getenv` and `setenv`. See https://gist.github.com/Nzbuu/7c657a3b22f535eb41dc55e12e4440da. – Nzbuu Jun 16 '16 at 18:06
  • 1
    @Nzbuu two things to note: 1) `System.getenv` returns the environment variables at the time MATLAB process was launched (JVM is embedded in MATLAB), this explains why it is not picking up change from `setenv`. This is different from `system` which spawns new processes 2) the `cmd.exe` shell has some private variables that are not displayed by default (leftover from MS-DOS days). One trick is to change the command executed to `cmd = 'set "';` to enumerate them, see http://stackoverflow.com/q/10431689/97160, http://blogs.msdn.com/b/oldnewthing/archive/2010/05/06/10008132.aspx for more info. – Amro Jun 16 '16 at 20:30
  • 1
    that last hack (set + space + doublequote) is actually a bug that became a feature :) https://blogs.msdn.microsoft.com/oldnewthing/20140425-00/?p=1143/ – Amro Jun 16 '16 at 20:36
  • @Amro, I figured that it was the environment variables at the time MATLAB starts. However, that does make it significantly less useful because it does not match with `getenv` and `setenv`. Hence, I think that the "correct" answer should be the `system` based one. – Nzbuu Jun 17 '16 at 08:44
  • I think that it's worth highlighting this limitation in the answer, at least. – Nzbuu Jun 17 '16 at 08:56
  • 1
    @Nzbuu: done. I also combined both methods into a helper function (`system` based-one being the default) – Amro Jun 17 '16 at 10:34