首页 > 解决方案 > 带有一个参数的 zsh export 似乎并没有真正创建环境变量

问题描述

命令

export FOO

根据我的理解,应该创建一个环境变量FOO(具有空白值),即使这个变量以前不存在并且没有提供值。这个立场似乎得到了zsh手册的支持。请参阅以下内容man zshbuiltins

export [ name[=value] ... ]
    The specified names are marked for automatic export to the environment of subsequently executed commands.    Equivalent
    to typeset -gx.  If a parameter specified does not already exist, it is created in the global scope.

但是,当我使用 C 的getenv函数时,没有注册这个环境变量。这是一个简单的例子。考虑以下程序:

 % cat foo.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    const char* foo = getenv("FOO");
    if ( foo == NULL ) {
        printf("The environment variable 'FOO' does not exist!\n");
    } else {
        printf("%s\n", foo);
        return 0;
    }
}

编译它:

 % gcc --version
gcc (GCC) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 % gcc foo.c -o foo

考虑以下三个执行:

 % ./foo
The environment variable 'FOO' does not exist!
 % export FOO
 % ./foo
The environment variable 'FOO' does not exist!
 % export FOO=BAR
 % ./foo
BAR

中间情况有什么问题?它不应该显示一个空行吗?

标签: cenvironment-variableszshgetenv

解决方案


请注意,您不需要编写自己的程序来显示环境变量。该env命令已经存在:-)

这是一个至少可以追溯到 40 年前最早的 UNIX shell 的怪癖。现代 shell(包括 bash、zsh 和 ksh)都表现出这种怪癖。怪癖是,如果您export VAR并且VAR尚未被分配一个值,则它被标记为导出,但在您为其分配一个值之前实际上不会在导出的环境中。您可以使用这些 shell 中的任何一个亲自看到这一点;不仅仅是zsh:

$ export FOO
$ env | grep FOO
$ FOO=''
$ env | grep FOO
FOO=
$ FOO=bar
$ env | grep FOO
FOO=bar
$ BAR=''
$ export BAR
$ env | grep BAR
BAR=

最后一个例子暗示了为什么export会这样。


推荐阅读