2

I mean to tell in Octave if a given environment variable exists.

Something that works in most cases is size(getenv(varname))(1). If this equals to 1, the variable exists. But if this equals 0, the variable may not exist or it may exist and be set to a null value.

How can I distinguish these two cases? Can this be done "natively" in Octave?

I would like my script to work irrespective of the host OS and shell.

In POSIX one could issue a system call and read the results. Then for Windows one would have to check in another way, and write a wrapper that deals with both cases separately.


EDIT (tl;dr)

I was using a defined/not-defined environment variable to handle compilation cases, via a combination of

if(DEFINED ENV{ENV_TEST})
  add_definitions(-DENV_TEST=$ENV{ENV_TEST})
endif()

in CMakeLists.txt and

#ifdef ENV_TEST
    cout << "ENV_TEST is defined and set to \'" ENV_TEST "\'" << endl;
#else
    cout << "ENV_TEST is not defined" << endl;
#endif

in myprog.cc. This is an MCVE-fication of my actual case, where the three possible states (1. not defined, 2. defined and null, 3. defined and not null) produce different results. In my actual case, I only needed to distinguish #1 vs. #2 (then the question), but I could turn all my #2 cases into #3 cases so now Octave also knows about it. The downside is that this was deployed across several computers, so instead of writing the Octave code that would handle this right away, I considered changing handling as described above. I am not sure this will not have side effects...

  • MATLAB has [`exist()`](https://ch.mathworks.com/help/matlab/ref/exist.html). Doesn't Octave as well? – Adriaan Aug 12 '20 at 10:31
  • @Adriaan - I think that is for Octave variables (plus files, etc.; and I guess it's the same with Matlab), not environment variables. Ref: https://octave.sourceforge.io/octave/function/exist.html – sancho.s ReinstateMonicaCellio Aug 12 '20 at 11:09
  • I don’t think you can do this is a POSIX shell, so Octave wouldn’t be able to do it either. – Cris Luengo Aug 12 '20 at 13:30
  • Well, [I was wrong](https://stackoverflow.com/questions/3601515/how-to-check-if-a-variable-is-set-in-bash). So if you are on a POSIX system (i.e. anything but Windows), then you can use a `system` call in Octave to query if the variable is set. Maybe Windows has a way to do this also. – Cris Luengo Aug 12 '20 at 13:40
  • @CrisLuengo - The system call way in POSIX is what I thought, even if not posted. That is why I later edited to include any OS/shell. Of course, one can write a wrapper `if` that deals with the different cases separately. Will edit. – sancho.s ReinstateMonicaCellio Aug 12 '20 at 14:03
  • Right, so if someone knows how to do this on Windows, then you have a solution for the two cases, and can write Octave code with `if isunix ... else ...`. – Cris Luengo Aug 12 '20 at 14:05
  • You may report it as a MATLAB incompatible bug in Octave bug tracker. In MATLAB If name is not found, an empty matrix [] is returned (instead of an empty string). As a workaround you can use `system` command as suggested by @CrisLuengo . In Windows also you can use `system` command to run for example powershell. – rahnema1 Aug 12 '20 at 14:13
  • The documentation to `setenv` makes me believe that on Windows you cannot define a variable to have a null value: "`setenv(name)` assigns a null value to `name`. This syntax is equivalent to `setenv(name,'')`. On the Microsoft® Windows® platform, this syntax is equivalent to undefining the variable. On most UNIX® platforms, it is possible to have an environment variable defined as empty." – Cris Luengo Aug 12 '20 at 14:20
  • @CrisLuengo Its [doc](https://www.mathworks.com/help/matlab/ref/getenv.html) says that. – rahnema1 Aug 12 '20 at 14:20
  • @CrisLuengo It says `[]`. It is double matrix instead of char matrix. – rahnema1 Aug 12 '20 at 14:30
  • @rahnema1: You are right, it does also show `[]`, not in the description text, but right above that. I have submitted feedback to the page, hopefully they'll fix that soon. – Cris Luengo Aug 12 '20 at 14:35
  • While this is an interesting question in its own right, may I ask what your use-case is? – Tasos Papastylianou Aug 12 '20 at 16:01
  • @TasosPapastylianou - I have sometimes used null environment variables as signals. At this point, I don't have an example where I am required to consider the three options for a variable (not set, set but null, not null) though. – sancho.s ReinstateMonicaCellio Aug 12 '20 at 16:12
  • Fair enough. The reason I ask is because your particular problem may have a better solution. E.g. rather than try to detect environmental variables from within octave specifically, they could be handled via a bash/batch script that does some preprocessing on the basis of those environmental variables first, and then calls octave appropriately. Or you could have an external bash script which does something based on those environmental variables, and call that from within octave. – Tasos Papastylianou Aug 12 '20 at 20:48
  • @TasosPapastylianou - Please see edit. I didn't mean to turn this question into something that long... – sancho.s ReinstateMonicaCellio Aug 13 '20 at 09:21
  • Thanks for the update. Yeah, my approach would definitely be to either detect environment variables in bash, and create an octave-friendly config file or something like this, or to consider a completely different approach not involving undefined vs null variables at all. I don't think trying to detect this from within octave offers anything useful here. – Tasos Papastylianou Aug 14 '20 at 00:40

1 Answers1

-1

@sancho.sReinstateMonicaCellio, If you don't have a specific use case then this is either a XY problem (see http://xyproblem.info) or you're wasting people's time by writing a misleading question that boils down to "Shouldn't GNU Octave provide a way to determine if an env var is defined?" See https://octave.org/doc/v4.0.1/Environment-Variables.html.

I can't speak to why the GNU Octave developers did not provide a mechanism for determining if an env var is not defined. But I'll bet it has a lot to do with the general design of the language.

You wrote "I would like my script to work irrespective of the host OS and shell.". The problem is that your question is independent of the host OS and shell. The problem is that GNU Octave apparently does not provide an API for distinguishing whether an env var is unset or set to an empty string. That has nothing to do with the OS or shell from which you launched GNU Octave.

Kurtis Rader
  • 6,734
  • 13
  • 20
  • 1
    This is a comment, not an answer. – Cris Luengo Aug 13 '20 at 06:07
  • Please see edit. I didn't mean to turn this question into something that long... PS: I know "The problem is that GNU Octave apparently does not provide an API for distinguishing whether an env var is unset or set to an empty string." That is the whole point of the question. – sancho.s ReinstateMonicaCellio Aug 13 '20 at 09:24