我通过包装 std::getenv
、setenv
和 environ
编写了用于在 C++ 中处理环境变量的小型便利函数。除了设置和获取环境变量外,我还提供了检查当前环境是否包含特定变量的功能。
#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;
}
然而,by definition , 这只允许访问 NAME=VALUE
形式的环境变量。
在 bash
中,我可以执行以下操作:
$> export SOME_VAR
$> export -p | grep SOME_VAR
declare -x SOME_VAR
显然,SOME_VAR
是在某处定义的,即使我没有给它赋值。但是,当我运行 printenv
时,它使用的方法与我在包装器中使用的方法相同,但未列出 SOME_VAR
。我看过 /proc/self/environ
但这只列出了具有赋值的变量。
我的问题是:
- 定义为
SOME_VAR_WITH_VALUE=42
和SOME_VAR_WITHOUT_VALUE
的环境变量有什么区别。 - 在 C/C++ 中是否可以访问没有值的环境变量?
最佳答案
Shell 有一个概念 internal and exported environment variables .
像 ABC=xyz
这样的 shell 命令设置了一个内部变量(可以在 Bash 中使用 set
看到)。
要导出内部变量,可以使用 export
命令。
export ABC=xyz
将创建一个内部变量并导出它(导出的可以使用env
查看)。
export ABC
本身并没有定义任何变量,它只是标记要导出的ABC
,何时它被定义。
例如试试这个:
$ ABC=xyz
$ set | grep ABC
ABC=xyz
$ env | grep ABC
现在使用 export
:
$ export ABC
$ set | grep ABC
$ env | grep ABC
$ ABC=xyz
$ set | grep ABC
ABC=xyz
$ env | grep ABC
ABC=xyz
注意变量在设置时是如何导出的。所以export ABC
纯粹是一个shell特性,它不修改环境。它没有 API。
要将环境变量设置为空值,请使用 export ABC=""
:
$ export ABC=""
$ env | grep ABC
ABC=
关于c++ - 访问没有赋值的 Linux 环境变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65140514/