set +a 不会取消设置 -a 标志

set +a 不会取消设置 -a 标志

在 Mac 10.11.6 上,使用 GNU bash 版本 3.2.57(1)-release (x86_64-apple-darwin15) 该set +a命令似乎不起作用:

script.py

#!/usr/bin/python
import os
print("VAR0 is:", os.environ.get("VAR0")

命令:

$ VAR0=abc
$ ./script.py
('VAR0 is:', None)   # expected
$ set -a
$ VAR0=abc
$ ./script.py
('VAR0 is:', 'abc')   # expected, VAR0 has been exported to the environment and script.py has access to it
$ set +a
$ VAR0=def
$ ./script.py
('VAR0 is:', 'def')   # <= unexpected

答案1

你误解了它的set -a作用。如果导出变量,则对该变量的更改始终会反映到环境中。 (这对于 的历史实现来说并不总是如此sh,但在所有现代的、符合 POSIX 的 shell 中都是如此。)该-a选项仅强制导出变量,即使它之前不是:默认情况下是一个赋值创建一个 shell 变量,但当-a生效时,赋值会导致该变量被导出,即使它尚未导出。

set +a取消设置该-a选项。更改导出变量的值会影响环境(无论-a是否有效)。

答案2

要点:是的,set +a未设置set -a,但变量不会因此而取消导出。然后需要取消导出或取消设置每个变量。


该选项allexport(与 相同set -a)允许自动导出新的改变了变量。激活该选项之前存在的变量set -a将不会被导出。

测试前两点:

  1. 的条件set -a可以用 打印shopt -po allexport。并且可以用and
    来改变。shopt -os allexportshopt -ou allexport

    $ shopt -po allexport
    set +o allexport
    
    $ set -a
    $ shopt -po allexport
    set -o allexport
    
    $ set +a
    $ shopt -po allexport
    set +o allexport
    
  2. shell 测试环境变量的方法是检查命令的输出environment,实际上是检查grep

    $ env | grep PATH
    PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
    

不需要来自 python 的外部程序(需要在第一次调用时编译)。如果这让你高兴的话,你仍然可以使用它,但没有真正的必要。

如果该选项未设置(set +a )。 A新的变量意志不是被出口。

$ unset VAR0
$ VAR0=abc
$ env | grep VAR0
                      # nothing is printed.

或者,如果您仍然想要您的程序:

$ ./envtest.py
VAR0 is: None

如果-a更改选项,则在更改之前不会导出 var:

$ set -a
$ shopt -po allexport
set -o allexport
$ env | grep VAR0
$ ./envtest.py
VAR0 is: None

如果变量改变:

$ VAR0=bcd
$ env | grep VAR0
VAR0=bcd
$ ./envtest.py
VAR0 is: bcd

set +a但如果应用该变量,该变量将保留在环境中:

$ set +a
$ env | grep VAR0
VAR0=bcd
$ ./envtest.py
VAR0 is: bcd

即使 var 改变了,它仍然是环境的一部分:

$ VAR0=xyz
$ env | grep VAR0
VAR0=xyz
$ ./envtest.py
VAR0 is: xyz

直到它被取消导出(删除导出属性):

$ declare +x VAR0

或者它只是unset

$ env | grep VAR0
VAR0=xyz
$ unset VAR0
$ env | grep VAR0

不,分配空值是不一样的:

$ VAR0=''
$ env | grep VAR0
VAR0=

您的程序没有清楚地显示这一点:

$ ./envtest.py
VAR0 is: 

答案3

这是因为对本地 shell 变量的赋值现在正在影响环境变量。如果您首先取消设置该变量,那么以后的赋值只能像以前一样作用于本地 shell 变量:

$ unset VAR0
$ VAR0=def
$ ./script.py
('VAR0 is:', 'None')

相关内容