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:
SOME_VAR_WITH_VALUE=42
and SOME_VAR_WITHOUT_VALUE
.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=
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With