使用 Sub-shell 评估函数时环境变量不可见
Environment Variable Not Visible when Evaluating a Function with a Sub-shell
这是我正在编写的更复杂脚本的一个最小示例。我想要做的关键是让 $FOO
对函数 foo
.
第二行中的子 shell 可见
然而,如图所示,它在第一次评估中不可见,但在第二次评估中奇怪地可见。
❯ function foo() {
echo "export FOO=BAR"
echo "export CAR=$(echo $FOO)"
}
~
❯ eval $(foo)
~
❯ echo $CAR
~
❯ eval $(foo)
~
❯ echo $CAR
BAR
eval $(foo)
扩展为:
eval 'export FOO=BAR export CAR=$(echo $FOO)'
export
的效果是导致两个分配都被处理 'at the same time' 并且由于 FOO
在这行代码之前未知,因此第二个分配变为 CAR=$(echo '')=''
.只有在第 2 个 eval $(foo)
,FOO
才有一个值,所以 CAR=BAR
.
为了绕过这个副作用并获得 CAR=BAR
(对于第一个 eval $(foo)
),您可以删除 export
或让函数在两者之间打印 ;
两个 export
s(明确地将 export
s 分开为两个单独的命令),例如:
# remove 'export'
foo() {
echo "FOO=BAR"
echo "CAR=$(echo $FOO)"
}
# explicitly separate into 2 commands via a ';'
foo() {
echo "export FOO=BAR ;" # notice the ';' appended on the end
echo "export CAR=$(echo $FOO)"
}
对于第二个 foo()
定义,eval $(foo)
扩展为:
eval 'export FOO=BAR ; export CAR=$(echo $FOO)'
在我们 parse/execute CAR=$(echo $FOO)
.
之前用两个单独的命令 FOO
赋值
我们可以通过一个简化示例看到 export
的这种行为(没有 Gordon Davisson 的评论中提到的问题):
$ export A=3 B="$A"
$ typeset -p A B
declare -x A="3"
declare -x B="" # A does not have a value so B=""
$ export A=3 B="$A"
$ typeset -p A B
declare -x A="3"
declare -x B="3" # A now has a value (from 1st run) so B=3
这是我正在编写的更复杂脚本的一个最小示例。我想要做的关键是让 $FOO
对函数 foo
.
然而,如图所示,它在第一次评估中不可见,但在第二次评估中奇怪地可见。
❯ function foo() {
echo "export FOO=BAR"
echo "export CAR=$(echo $FOO)"
}
~
❯ eval $(foo)
~
❯ echo $CAR
~
❯ eval $(foo)
~
❯ echo $CAR
BAR
eval $(foo)
扩展为:
eval 'export FOO=BAR export CAR=$(echo $FOO)'
export
的效果是导致两个分配都被处理 'at the same time' 并且由于 FOO
在这行代码之前未知,因此第二个分配变为 CAR=$(echo '')=''
.只有在第 2 个 eval $(foo)
,FOO
才有一个值,所以 CAR=BAR
.
为了绕过这个副作用并获得 CAR=BAR
(对于第一个 eval $(foo)
),您可以删除 export
或让函数在两者之间打印 ;
两个 export
s(明确地将 export
s 分开为两个单独的命令),例如:
# remove 'export'
foo() {
echo "FOO=BAR"
echo "CAR=$(echo $FOO)"
}
# explicitly separate into 2 commands via a ';'
foo() {
echo "export FOO=BAR ;" # notice the ';' appended on the end
echo "export CAR=$(echo $FOO)"
}
对于第二个 foo()
定义,eval $(foo)
扩展为:
eval 'export FOO=BAR ; export CAR=$(echo $FOO)'
在我们 parse/execute CAR=$(echo $FOO)
.
FOO
赋值
我们可以通过一个简化示例看到 export
的这种行为(没有 Gordon Davisson 的评论中提到的问题):
$ export A=3 B="$A"
$ typeset -p A B
declare -x A="3"
declare -x B="" # A does not have a value so B=""
$ export A=3 B="$A"
$ typeset -p A B
declare -x A="3"
declare -x B="3" # A now has a value (from 1st run) so B=3