在 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
将不会被导出。
测试前两点:
的条件
set -a
可以用 打印shopt -po allexport
。并且可以用and
来改变。shopt -os allexport
shopt -ou allexport
$ shopt -po allexport set +o allexport $ set -a $ shopt -po allexport set -o allexport $ set +a $ shopt -po allexport set +o allexport
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')