C++程序中未找到环境变量UID

3
有人能解释一下为什么我可以使用下面的代码扩展PATH,但无法扩展UID吗?
#include <iostream>
#include <string>
#include <regex>

std::string ExpandEnvironmentVariables(std::string path)
{
    static std::regex env("\\$\\{([^}]+)\\}");
    std::smatch match;
    while (std::regex_search(path, match, env))
    {
        const char * s = getenv(match[1].str().c_str());
        const std::string var(s == NULL ? "(empty)" : s);
        path.replace(match[0].first, match[0].second, var);
    }

    return path;
}

int main(int argc, char* argv[])
{
    std::string UID = "${UID}";
    std::cout << UID << " ==> " << ExpandEnvironmentVariables(UID) <<  std::endl;

    std::string PATH = "${PATH}";
    std::cout << PATH << " ==> " << ExpandEnvironmentVariables(PATH) <<  std::endl;

    return 0;
}

输出结果如下:
./ExpandEnvironmentVariables
${UID} ==> (empty)
${PATH} ==> /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

在Bash中存在UID变量:

echo $UID
1000

1
我相信 UID 是一个内部的 Bash 变量,实际上并不是导出环境的一部分,因此无法通过 getenv 访问,但是 Bash 允许通过 $var 语法访问它。 - user2100815
1个回答

3
并非所有的shell变量在bash中都被导出。您可以像这样检查shell变量状态:

不是所有的shell变量在bash中都被导出。 您可以使用以下方式检查shell变量状态:

$ declare -p UID
declare -ir UID="1000"

这意味着变量具有整数属性(-i),并且是只读的(-r)。导出的变量看起来像这样:
$ declare -p PATH
declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
< p > -x 表示将变量导出并添加到子进程的进程环境中。


所以我必须使用 getuid() - 这会给我正确的 UID(http://man7.org/linux/man-pages/man2/getuid.2.html) - SBF
@SBF:考虑一下你是否想要关注EUID(有效UID-geteuid())与真实UID(getuid())之间的区别。很有可能你不想处理这些复杂性,尤其是大多数情况下结果都是相同的。但如果它们不同,你使用哪个就很重要了,并且取决于你想要跟踪什么。总的来说,环境变量并不是非常可靠的。如果有人运行UID=0 bash -c 'echo $UID'会发生什么?(部分答案:bash会说这是一个只读变量-但我不想把公司的安全寄托在没有漏洞的保证上!) - Jonathan Leffler
我知道UID/EUID是只读的,但为什么它们没有被导出呢?我不想硬编码需要存储守护进程PID文件的路径,所以我想使用/var/run/user/${UID}/mydaemon.pid而不是/var/run/user/1000/sbfspotupload.pid - 无论如何,我用getuid()测试过了,这很好用。我可以调整我的代码来处理特殊的UID/EUID变量。 - SBF
2
只是为了澄清,此目录的路径应从 XDG_RUNTIME_DIR 变量 中读取。 - Florian Weimer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接