bash 函数中的局部变量

bash 函数中的局部变量

我对在 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())。

相关内容