我对在 bash 函数中设置局部变量感到困惑。
看来使用
local dgt
local ltr
local braces
local da
可能比使用更安全
local dgt ltr braces da
我担心变量可能没有被定义为本地变量,或者没有设置值。这会发生吗?
例如,考虑
local foo="$(mycmd)"
命令的退出状态被局部变量创建的退出状态覆盖。
那么正确的代码是
local foo
foo=$(mycmd)
答案1
未定义为本地或未设置值。这会发生吗?
只要本地命令本身最初在语法上是正确的,它也将被定义。本地命令不关心本地命令评估之前或之后可能发生的任何命令替换(在子 shell 中执行)的退出值。
$ f() { local x=$(false); declare -p x; }; f; declare -p x
declare -- x=""
bash: declare: x: not found
至少有意如此。然而,错误可能无法使其按您期望的方式工作,特别是在定义数组值在 Bash 的早期版本中。因此,有时确实将定义与声明分开可能会更好。
答案2
FWIW,一些差异:
$ bash -c 'f() { local a="$(exit 3)" b="$?"; echo "$b"; }; f'
3
$ bash -c 'f() { local a="$(exit 3)"; local b="$?"; echo "$b"; }; f'
0
$ bash -c 'f() { local a="$(exit 3)" á=x b="$?"; echo "$? $b"; }; f'
environment: line 0: local: `á=x': not a valid identifier
1 3
$ mksh -c 'a=0; f(){ local á; local a; a=1; }; f; echo "$a"'
mksh: typeset: á: is not an identifier
0
$ mksh -c 'a=0; f(){ local á a; a=1; }; f; echo "$a"'
mksh: typeset: á: is not an identifier
1
请注意,与许多其他 shell 相反,bash 不允许您像在父作用域中local
声明变量一样对变量进行 decalre。readonly
尽管如此,就像 for local Ûnsupported¹ other_var
, in一样local readonly_var other_var
,我发现 in bash
,other_var
仍然最终被声明为local
。
1local Ûnsupported
实际上可以在 中工作bash
,但仅适用于Û
在单个字节上编码的区域设置(并被分类为isalpha()
)。