带一个参数的 zsh export 似乎并没有真正创建环境变量
zsh export with one argument does not seem to actually create environment variable
命令
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
中间的情况有什么问题?它不应该显示一个空行吗?
这里有一些错误。首先,让我们将程序更改为直接使用环境变量,避免 getenv
:
中出现错误的可能性
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[], char *arge[])
{
for (char **p = arge; *p; ++p)
if (0 == strncmp(*p, "FOO", 3))
{
puts(*p);
return 0;
}
}
现在,如果我们构建它并重新执行它 zsh
,我们不会像预期的那样得到任何输出。
如果我们 export FOO
并执行它,我们再次没有输出,但 export | grep FOO
显示 FOO=''
。所以 zsh
did 将它定义为一个空字符串,但是 zsh 未能将它传递给程序(或 [=17= 中的环境变量处理中的某些内容) ] 例程搞砸了)。
但是,重新开始zsh
,执行两次export FOO
,然后程序。现在输出是 FOO=
。但是export | grep FOO
还是显示FOO=''
。所以在zsh
中似乎有一些隐藏状态:有时它不导出定义的变量。
请注意,您不需要编写自己的程序来显示环境变量。 env
命令已经存在:-)
这是一个至少可以追溯到四十年前最早的 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
会这样。
命令
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
中间的情况有什么问题?它不应该显示一个空行吗?
这里有一些错误。首先,让我们将程序更改为直接使用环境变量,避免 getenv
:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[], char *arge[])
{
for (char **p = arge; *p; ++p)
if (0 == strncmp(*p, "FOO", 3))
{
puts(*p);
return 0;
}
}
现在,如果我们构建它并重新执行它 zsh
,我们不会像预期的那样得到任何输出。
如果我们 export FOO
并执行它,我们再次没有输出,但 export | grep FOO
显示 FOO=''
。所以 zsh
did 将它定义为一个空字符串,但是 zsh 未能将它传递给程序(或 [=17= 中的环境变量处理中的某些内容) ] 例程搞砸了)。
但是,重新开始zsh
,执行两次export FOO
,然后程序。现在输出是 FOO=
。但是export | grep FOO
还是显示FOO=''
。所以在zsh
中似乎有一些隐藏状态:有时它不导出定义的变量。
请注意,您不需要编写自己的程序来显示环境变量。 env
命令已经存在:-)
这是一个至少可以追溯到四十年前最早的 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
会这样。