当脚本来自函数内时,Bash shell变量会丢失

Tom*_*man 6 bash shell scope function

我在Cygwin bash版本4.3.42(4)中遇到了一个奇怪的(对我来说)问题.当在函数内调用前者时,在调用脚本中声明的Shell变量不会在调用脚本中保留.

我有以下两个脚本来说明问题.script1.sh调用script2.sh设置两个变量.如果通过script1中的函数调用script2,则变量将丢失,而如果在没有函数调用的情况下调用script2,则变量将按预期保持不变.所有对script2的调用都是通过"source"完成的.

script1.sh:

#!/usr/bin/bash
#
# calling script
#
function sourceit()
{
    source scripts/script2.sh
}

sval=1
echo "$0 before sourceit(); rval=$rval sval=$sval PID=$$"
sourceit
echo "$0 after sourceit(); rval=$rval sval=$sval PID=$$"

sval=3
echo "$0 before source; rval=$rval sval=$sval PID=$$"
source scripts/script2.sh
echo "$0 after source; rval=$rval sval=$sval PID=$$"
Run Code Online (Sandbox Code Playgroud)

script2.sh

#!/usr/bin/bash
#
# called script
#
echo "$0 before declare; rval=$rval sval=$sval PID=$$"
sval=2
declare -r rval=2
echo "$0 after declare; rval=$rval sval=$sval PID=$$"
Run Code Online (Sandbox Code Playgroud)

结果:

scripts/script1.sh before sourceit(); rval= sval=1 PID=1752
scripts/script1.sh before declare; rval= sval=1 PID=1752
scripts/script1.sh after declare; rval=2 sval=2 PID=1752
scripts/script1.sh after sourceit(); rval= sval=2 PID=1752
scripts/script1.sh before source; rval= sval=3 PID=1752
scripts/script1.sh before declare; rval= sval=3 PID=1752
scripts/script1.sh after declare; rval=2 sval=2 PID=1752
scripts/script1.sh after source; rval=2 sval=2 PID=1752
Run Code Online (Sandbox Code Playgroud)

我没有看到任何子壳被创建(到处都显示相同的PID).

我错过了一个更好的bash脚本点吗?

Joh*_*ger 3

\n

我有以下两个脚本来说明这个问题。script1.sh 调用 script2.sh 设置两个变量。如果通过 script1 中的函数调用 script2,则变量将丢失,

\n
\n\n

嗯,不,您的输出显示从函数返回后变量的值rval丢失,但变量的值sval被保留。

\n\n
\n

而如果在没有函数调用的情况下调用 script2,变量将按预期持续存在。script2 的所有调用都是通过“source”完成的。

\n
\n\n

rval由于和的行为之间存在区别sval,因此您应该寻找script2.sh它们处理方式的差异,等等瞧\xc3\xa0!事实证明,是通过内置rval函数赋值的,而是直接赋值的。然后查看 的文档,我们发现:declaresvaldeclare

\n\n
\n

当在函数中使用时,使每个名称成为本地名称,与local命令一样。

\n
\n\n

中的局部变量bash就像大多数其他语言中的局部变量一样——它们与具有相同名称的其他变量不同,并且在它们的作用域内,它们隐藏了包含作用域中的类似命名的变量。sval因此,您的代码在每种情况下都在各处设置和检查相同的变量,但它在函数内部设置和检查的变量与其他地方不同。 rval

\n