在 C / C++ 中打印所有环境变量

Posted

技术标签:

【中文标题】在 C / C++ 中打印所有环境变量【英文标题】:Printing all environment variables in C / C++ 【发布时间】:2010-01-18 10:30:29 【问题描述】:

如何获取 C 和/或 C++ 中所有环境变量的列表?

我知道getenv 可以用来读取环境变量,但是如何将它们全部列出呢?

【问题讨论】:

使用system(env)调用环境怎么样? 【参考方案1】:

环境变量作为envp 参数提供给main() - 一个以空字符结尾的字符串数组:

int main(int argc, char **argv, char **envp)

  for (char **env = envp; *env != 0; env++)
  
    char *thisEnv = *env;
    printf("%s\n", thisEnv);    
  
  return 0;

【讨论】:

如果你在windows下工作,如果你有编译器,为什么不直接运行看看呢?让我们知道进展如何。 虽然受到广泛支持(我不知道有任何编译器不支持它),但不能保证 main 中使用“envp”参数,只有“argc”和“argv”。 "envp" 也使它成为 main() 的局部变量。一个更可移植的解决方案是查看几乎每个编译器都提供的“环境”外部(全局),以及 getenv() 和 setenv() 函数(它们应该确保操作进程环境的完整性) .许多实现还提供了一个 putenv() 函数,但这个函数可能无法确保环境的完整性。 (请参阅文档,评论空间不足。)【参考方案2】:
#include <stdio.h>

extern char **environ;

int main() 
  char **s = environ;

  for (; *s; s++) 
    printf("%s\n", *s);
  

  return 0;

【讨论】:

您的示例中有一个错误。第一个环境变量被打印两次。 你是 100% 正确的。我已将 i 的初始值从 0 更新为 1。 这个解决方案的优点是它不需要在main()中。如果你把它放在一个大而复杂的程序的中间,它工作得很好。谢谢!! 这是一个特定于 posix 的 API。另一方面,getenv 是一个 C 标准库函数,这意味着它适用于所有 C 兼容的操作系统。 @andrewrk getenv() 不允许遍历所有环境变量,AFAIK。【参考方案3】:

我认为你应该检查environ。使用“人环境”。

【讨论】:

【参考方案4】:

您的编译器可能会为提供额外环境变量信息的主函数提供非标准扩展。 MS 编译器和大多数 Unix 版本都有这个版本的 main:

int main (int argc, char **argv, char **envp)

其中第三个参数是环境变量信息 - 使用调试器查看格式是什么 - 可能是一个以 null 结尾的字符串指针列表。

【讨论】:

【参考方案5】:
LPTCH WINAPI GetEnvironmentStrings(void);

http://msdn.microsoft.com/en-us/library/ms683187%28VS.85%29.aspx

编辑:仅适用于 Windows。

【讨论】:

【参考方案6】:
int main(int argc, char **argv, char** env) 
   while (*env)
      printf("%s\n", *env++);
   return 0;

【讨论】:

【参考方案7】:
int main(int argc, char* argv[], char* envp[]) 
   // loop through envp to get all environments as "NAME=val" until you hit NULL.

【讨论】:

【参考方案8】:

在大多数环境中,您可以将 main 声明为:

main(int argc,char* argv[], char** envp)

envp 包含所有环境字符串。

【讨论】:

【参考方案9】:

如果您在 Windows 操作系统上运行,那么您也可以调用 GetEnvironmentStrings(),它会返回一个以空字符结尾的字符串块。

【讨论】:

【参考方案10】:

这里的大多数答案都指出了从大多数编译器支持的参数到 main 中选择环境的可能性。而亚历克斯的回答:

#include <stdio.h>
extern char **environ;

int main() 
  char **s = environ;
  for (; *s; s++) 
      printf("%s\n", *s);
  
  return 0;

应该始终有效,我想知道当您在 C 代码(putenv、unsetenv)中操作环境时,char **environ 会发生什么。然后environ 可能指向其他地方(重新分配时,可能取决于系统实现)。如果我们坚持传递给 main 的参数并将其传递给需要它的函数,则此指针可能不再指向当前环境。

【讨论】:

这个答案与@user1602017 给出的答案有何不同? @user160217 提供的答案没有任何问题,我打算指出他和最佳答案之间的区别,可能是通过重新分配。如果我有足够的积分,我会使用评论来代替要做到这一点。我假设了额外的价值。从 **environ fresh 获取应该确保获取最近的值 - 取决于操作系统。【参考方案11】:

对我来说,或多或少可移植的 C 代码解决方案如下:

#include <stdlib.h>
void printenv() 
    char ** env;
#if defined(WIN) && (_MSC_VER >= 1900)
    env = *__p__environ();
#else
    extern char ** environ;
    env = environ;
#endif
    for (env; *env; ++env) 
        printf("%s\n", *env);
    

解释:

    在 Linux、Windows、Solaris、AIX 上成功测试。

    也在新版本的 Visual Studio 上成功测试。关键是,至少从 VS 2017(可能更早)开始,environ 全局变量不再被识别。如果你打开头文件 C:\Program Files\Windows Kits\10\Include\x.x.x.x\ucrt\stdlib.h 你会看到这个全局变量被函数__p__environ()替换了。不幸的是,它没有很好地记录。在https://docs.microsoft.com/en-us/cpp/c-runtime-library/environ-wenviron?view=msvc-170 中没有任何消息。

    这种方法的优点是,如果不允许修改 main() 函数,添加 envp[] 也是合适的。

    关于 GetEnvironmentStrings(),它返回一个空列表。可能它适用于 C++ 而不适用于 C。我没有研究它。

【讨论】:

以上是关于在 C / C++ 中打印所有环境变量的主要内容,如果未能解决你的问题,请参考以下文章

C++动态库环境变量的传递

Linux下获取和设置环境变量

如何使用VS2005输出所有环境变量

环境变量的查看—env和printenv(环境变量打印)

Linux打印变量环境配置别名和文件删除操作

C++学习笔记