Reputation: 308
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
.Upvotes: 4
Views: 2299
Reputation: 85341
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=
Upvotes: 3
Reputation: 179809
Ultimately, bash
is just another Linux program. There's limited magic involved. It can alter the libc
environ
variables, but it can also have its own internal variables. If you don't see SOME_VAR_WITHOUT_VALUE
in /proc/sef/environ
, you can deduce that it's some kind of bash-internal variable.
Note that bash
, like most Linux programs, can be run multiple times in parallel. Environments are separate between processes. So even in C you can't access any of the bash environment variables directly. You're taking advantage of the fact that bash copies its environment to your environment, when your process is started. But env -i your_process
will stop even that.
Upvotes: 0
Reputation: 622
First try this:
export SOME_VAR
set | grep SOME_VAR
The second line will return nothing. That is because the first line doesn't define SOME_VAR
.
As for your two questions:
export VARIABLE
has no effect. It does not create variable with no value, nor does it change value of an already set variable.NULL
.Upvotes: 0