sh中局部变量的作用域
The scope of local variables in sh
我在调试递归函数时遇到了很多麻烦。事实证明,Dash 对局部变量的解释很奇怪。考虑以下片段:
iteration=0;
MyFunction()
{
local my_variable;
iteration=$(($iteration + 1));
if [ $iteration -lt 2 ]; then
my_variable="before recursion";
MyFunction
else
echo "The value of my_variable during recursion: '$my_variable'";
fi
}
MyFunction
在Bash中,结果是:
The value of my_variable during recursion: ''
但在 Dash 中,它是:
The value of my_variable during recursion: 'before recursion'
看起来 Dash 使局部变量在同一函数名称中可用。当我不知道何时以及哪个递归迭代更改了变量的值时,这有什么意义?如何避免问题?
这是由于您试图在最内层的调用中读取变量而未在其中显式设置它的结果。在那种情况下,该变量确实是函数的局部变量,但它从外部上下文(您将其设置为 "before recursion"
)继承了它的初始值。
因此,变量上的 local
标记仅影响函数调用返回后调用方中变量的值。如果在被调用函数中设置局部变量,它的值不会影响调用者中相同变量的值。
引用 dash 手册页:
Variables may be declared to be local to a function by using a local command. This should appear as the first statement of a function, and the syntax is
local [variable | -] ...
Local is implemented as a builtin command.
When a variable is made local, it inherits the initial value and exported and readonly flags from the variable with the same name in the surrounding scope, if there is one. Otherwise, the variable is initially unset. The shell uses dynamic scoping, so that if you make the variable x
local to function f
, which then calls function g
, references to the variable x
made inside g
will refer to the variable x
declared inside f
, not to the
global variable named x
.
The only special parameter that can be made local is “-”. Making “-” local any shell options that are changed via the set command inside the function to be restored to their original values when the function returns.
要确定特定上下文中变量的值,请确保始终在该上下文中明确设置它。否则,您依赖于各种 shell 的“后备”行为,这些行为可能因 shell 而异。
local
不是 POSIX 规范的一部分,因此 bash
和 dash
可以按照自己喜欢的方式自由实施。
dash
不允许使用 local
赋值,因此该变量是 unset 除非它从周围范围继承值。 (本例中,第二次迭代的周边范围为第一次迭代。)
bash
确实允许赋值(例如,local x=3
),并且总是创建一个变量默认空值,除非进行赋值。
我在调试递归函数时遇到了很多麻烦。事实证明,Dash 对局部变量的解释很奇怪。考虑以下片段:
iteration=0;
MyFunction()
{
local my_variable;
iteration=$(($iteration + 1));
if [ $iteration -lt 2 ]; then
my_variable="before recursion";
MyFunction
else
echo "The value of my_variable during recursion: '$my_variable'";
fi
}
MyFunction
在Bash中,结果是:
The value of my_variable during recursion: ''
但在 Dash 中,它是:
The value of my_variable during recursion: 'before recursion'
看起来 Dash 使局部变量在同一函数名称中可用。当我不知道何时以及哪个递归迭代更改了变量的值时,这有什么意义?如何避免问题?
这是由于您试图在最内层的调用中读取变量而未在其中显式设置它的结果。在那种情况下,该变量确实是函数的局部变量,但它从外部上下文(您将其设置为 "before recursion"
)继承了它的初始值。
因此,变量上的 local
标记仅影响函数调用返回后调用方中变量的值。如果在被调用函数中设置局部变量,它的值不会影响调用者中相同变量的值。
引用 dash 手册页:
Variables may be declared to be local to a function by using a local command. This should appear as the first statement of a function, and the syntax is
local [variable | -] ...
Local is implemented as a builtin command.
When a variable is made local, it inherits the initial value and exported and readonly flags from the variable with the same name in the surrounding scope, if there is one. Otherwise, the variable is initially unset. The shell uses dynamic scoping, so that if you make the variable
x
local to functionf
, which then calls functiong
, references to the variablex
made insideg
will refer to the variablex
declared insidef
, not to the global variable namedx
.The only special parameter that can be made local is “-”. Making “-” local any shell options that are changed via the set command inside the function to be restored to their original values when the function returns.
要确定特定上下文中变量的值,请确保始终在该上下文中明确设置它。否则,您依赖于各种 shell 的“后备”行为,这些行为可能因 shell 而异。
local
不是 POSIX 规范的一部分,因此 bash
和 dash
可以按照自己喜欢的方式自由实施。
dash
不允许使用 local
赋值,因此该变量是 unset 除非它从周围范围继承值。 (本例中,第二次迭代的周边范围为第一次迭代。)
bash
确实允许赋值(例如,local x=3
),并且总是创建一个变量默认空值,除非进行赋值。