shell 中导出变量的范围

Bha*_*iya 5 shell subshell variable

假设我有一个脚本,我在其中导出了一个变量,如下所示:

#!/bin/bash
foo(){
    eval export one=1
}
foo1(){
    eval export two=2
}
(foo)
foo1
echo "one=$one"
echo "two=$two"
Run Code Online (Sandbox Code Playgroud)

但是我得到了以下输出:

root@centos1:~>/tmp/test.sh
one=
two=2 
Run Code Online (Sandbox Code Playgroud)

什么可能是我无法看到的价值$one和可以看到的原因$two

PSk*_*cik 7

全局变量从它们被设置的那一刻起一直存在,直到它们被取消或进程结束的那一刻。全局(或局部)变量不会被无关的子进程继承(如果子进程是一个 fork(子 shell),那么它会获得所有内容的副本——导出的或非导出的)。

全局导出变量类似于全局变量,但它们也会被甚至不相关的子进程自动继承(作为进程环境的一部分)。(通过导出,您可以将变量传递给诸如 之类CXXFLAGS的进程make,这绝对不是您的 shell 的子shell,并且make产生的每个进程也将获得该变量。)

在您的示例中,()创建一个子shell,它获取所有内容的副本。该foo命令通过添加导出的变量来修改子外壳,然后子外壳在不使用导出变量的情况下结束(没有孙子继承它)。现在,没有信息从子进程隐式传输到父进程。孩子在他们的环境中所做的事情对他们的父母没有影响。这就是您的变量one未设置的原因。


顺便说一句,在这种情况下,那些evals 是不必要的eval