Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Linux environment variables without assigned value

I wrote small convenience functions for working with environment variables in C++ by wrapping std::getenv, setenv and environ. In addition to setting and getting the environment variables, I provided functionality to check if the current environment contains a certain variable.

#include <cstdlib>
#include <unistd.h>

template <typename VAR_TYPE>
void set(const std::string& variableName, VAR_TYPE varValue, bool overwrite = false) {
    if (!setenv(variableName.c_str(), std::string(variableValue).c_str(), overwrite)) {
      if (errno == ENOMEM) {
        throw std::bad_alloc();
      } else if (errno == EINVAL) {
        throw std::invalid_argument("Variable name invalid: "  + variableName);
      } else {
        throw std::runtime_error("Failed to set environment variable " + variableName);
      }
    }
  }

std::string load(const std::string& variableName, const std::string& defaultValue = "") {
    if (const char* envVariable = std::getenv(variableName)) {
      return std::string(envVariable);
    }
    return defaultValue;
  }

bool contains(const std::string& variableName) {
    for (char** currentEnviron = environ; *currentEnviron; currentEnviron++) {
      if (!std::strncmp(variableName.c_str(), *currentEnviron, variableName.length())) {
        return true;
      }
    }
    return false;
  }

However, by definition, this only allows to access environment variables that are in the form NAME=VALUE.

In bash, I can do the following:

$> export SOME_VAR
$> export -p | grep SOME_VAR
declare -x SOME_VAR

Apparently, SOME_VAR is defined somewhere, even if I dont assign a value to it. When I run printenv however, which uses the same methods I use in my wrapper, SOME_VAR is not listed. I have had a look at /proc/self/environ but this only lists variables with assigned value.

My questions are:

  1. What is the difference between an environment variable defined as SOME_VAR_WITH_VALUE=42 and SOME_VAR_WITHOUT_VALUE.
  2. Is there a possibility in C/C++ to access environment variables without values?
like image 482
sfun Avatar asked Sep 10 '25 09:09

sfun


1 Answers

Shell has a notion of internal and exported environment variables.

A shell command like ABC=xyz sets an internal variable (which can be seen in Bash using set).

To export an internal variable, there's the export command.

export ABC=xyz will create an internal variable and export it (exported ones can be seen using env).

export ABC by itself does not define any variable, it simple tags ABC to be exported, when it's defined.

Try this for example:

$ ABC=xyz
$ set | grep ABC
ABC=xyz
$ env | grep ABC

And now with export:

$ export ABC
$ set | grep ABC
$ env | grep ABC
$ ABC=xyz
$ set | grep ABC
ABC=xyz
$ env | grep ABC
ABC=xyz

Notice how the variable got exported the moment it was set. So export ABC is purely a shell feature, it does not modify the environment. There is no API for it.

To set an environment variable with an empty value, use export ABC="":

$ export ABC=""
$ env | grep ABC
ABC=
like image 136
rustyx Avatar answered Sep 13 '25 00:09

rustyx