【问题标题】:How to check if environment variable is set from C program如何检查是否从C程序设置了环境变量
【发布时间】:2015-01-17 21:37:02
【问题描述】:

我目前正在开发一个程序,如果设置了环境变量,我想打印特殊输出。

例如,假设我想要环境变量"DEBUG"

在我的 bash 命令提示符中,我通过输入以下命令来设置 DEBUGDEBUG=

然后在我的 C 程序中,我可以通过打印出 char **environ 的所有内容来验证此环境变量是否已设置。 DEBUG 确实出现在此环境打印输出中。

但是,我不知道如何检索此环境变量以进行条件检查。我试过像这样使用函数 getenv:

getenv("DEBUG")

如果我尝试像下面这样打印出这个输出,我会得到一个段错误:

printf("get env: %s\n", getenv("DEBUG"));

我什至在"HOME"这样的已知环境变量上尝试过这个:

printf("get env: %s\n", getenv("HOME"));

仍然会产生段错误。

有没有人有任何检查环境变量是否是从 C 程序中设置的经验?我什至遇到了问题,甚至拉动了一个阻止我这样做的环境变量。

【问题讨论】:

  • 您使用的是什么操作系统?
  • 我在 OSX 上,但我也在 unix/linix 服务器上进行测试

标签: c unix environment-variables


【解决方案1】:

getenv 在未设置请求的环境变量时返回NULL。因此,您的支票可能只是

if(getenv("DEBUG")) {
  // DEBUG is set
} else {
  // DEBUG is not set
}

注意shell和环境变量是有区别的;如果你想让一个变量出现在 shell 子进程的环境中,你必须在 shell 中export它:

export DEBUG=some_value

DEBUG=some_value
export DEBUG

光说DEBUG=some_value是不够的。

【讨论】:

  • 你如何用getenv("HOME");解释分段错误?
  • 他将 NULL 打印为字符串。
  • getenv("HOME") 不太可能返回 NULL,而且我怀疑 OP 在 linux 上使用 glibcprintf("%s\n", NULL); 实际上会输出 (null)
  • 我在 x86-64 Linux 上,当我尝试 printf("%s\n", NULL);(使用 glibc 2.19)时出现段错误。不过,您对$HOME 有意见。
  • 我只是做了同样的printf("%s\n", NULL);,当然发出了警告,但它没有崩溃,它只是输出(null),有什么区别?
【解决方案2】:

这是因为你没有包含stdlib.h,编译器假设getenv()返回int

你有两种选择,你可以声明getenv()like

char *getenv(const char *);

或包含stdlib.h,同样适用于printf(),但在这种情况下,标头为stdio.h

你应该启用编译器警告,在linux上gccclang都支持-Wall -Wextra -Werror,最重要的-Werror会在这种情况下阻止编译。

【讨论】:

    【解决方案3】:

    代码 sn-p:

       if(NULL == getenv("TIME_ELAPSED"))
        {
            putenv("TIME_ELAPSED=1");
        }
    

    我们还必须处理 putenv 的错误处理。有时它会返回 ENOMEM 空间不足,无法分配新环境。

    【讨论】:

      【解决方案4】:

      您需要确保正确声明了getenv(和printf)。

      对于getenv,您需要:

      #include <stdlib.h>
      

      如果你不声明它,当你调用它时可能会出现段错误。如果你要做到这一点,尝试使用它返回的值可能也会出现段错误。

      未声明的函数被处理为好像它们被声明为接受整数或双参数(取决于提供的内容)并且好像它们返回整数。如果int 与指针大小相同,这可能会起作用,但在指针为 64 位但整数仅为 32 的常见情况下,将指针视为整数传递将导致其一半的位被丢弃在地板上,使它几乎无法用作指针。

      总是在编译代码时指定-Wall,并确保注意警告。它们很重要。

      【讨论】:

      • @iharob:给定 64 位指针和 32 位整数,如果您调用将指针作为参数的未声明函数,则几乎不可避免会出现段错误,因为默认的 int 转换将下降指针的高位。
      • 我现在...由于您没有提到默认返回 int 问题,我添加了一个新答案来解决这个问题。
      • @iharob:它可能永远不会返回。但是我在答案中做了一个解释,fwiw。 (虽然正确的解释当然是“UB yadda yadda yadda。”)如果我有更多的精力,我会寻找骗子。
      • 感谢您的回复。我正在尝试编写自己的 stdlib 版本的函数,因此没有包含该库,但我会尝试将其添加到
      猜你喜欢
      • 2015-07-14
      • 2015-06-23
      • 1970-01-01
      • 2013-08-03
      • 1970-01-01
      • 2019-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多