通过在函数内部采购创建的 bash 数组具有局部作用域,但标量是全局的

Doc*_*ory 6 arrays macos bash scope function

考虑以下 bash 脚本:

#!/usr/bin/env /bin/bash

function sourcefile(){
  source /tmp/srcfile
  echo "Sourced array in func: ${sourcedarray[*]}"
  echo "Sourced scalar in func: ${sourcedscalar}"
}

globalarray=([0]="xyzzy" [1]="kaboom")
globalscalar="argle"

cat >/tmp/srcfile <<EOF
export sourcedscalar="bargle"
export sourcedarray=([0]="foo" [1]="bar")
EOF

sourcefile

echo "Global array: ${globalarray[*]}"
echo "Global scalar: ${globalscalar}"
echo "Sourced array: ${sourcedarray[*]}"
echo "Sourced scalar: ${sourcedscalar}"

Run Code Online (Sandbox Code Playgroud)

人们会合理地期望在输出中设置所有四个值,但至少对于 bash 版本3.2.57(1)-release(是的,是的,我知道:我们都为 Apple 的偏执狂买单),情况并非如此:

Sourced array in func: foo bar
Sourced scalar in func: bargle
Global array: xyzzy kaboom
Global scalar: argle
Sourced array:
Sourced scalar: bargle
Run Code Online (Sandbox Code Playgroud)

据我所知:

  • 通过获取文件在函数中创建的标量变量是在全局范围内创建的
  • 但是通过获取文件在函数中创建的数组变量是在本地范围内创建的,导出它不会改变这一点

委婉地说,这似乎不一致:有什么方法可以解决这种行为吗?

Soc*_*owi 6

正如评论中指出的那样,在更“新”版本的 bash 中,这不再是问题。对于 4.3 及以下版本,我们发现以下内容:

首先,分配是否在源脚本中没有任何作用;功能有所作为。但是,单独的功能也不会导致您的问题。只有 function + 的组合export导致数组是本地的。

如果您删除export作业前面的 ,则一切正常。在您的示例中,您无论如何都不必导出变量。实际上,由于 posix 中未指定数组,因此无法导出数组。

如果你想创建一个全局变量并导出它,那么使用declare -xg而不是export.

#!/usr/bin/env bash

function sourcefile(){
  source /tmp/srcfile
  echo "Sourced array in func: ${sourcedarray[*]}"
  echo "Sourced scalar in func: ${sourcedscalar}"
}

globalarray=([0]="xyzzy" [1]="kaboom")
globalscalar="argle"

cat >/tmp/srcfile <<EOF
declare -xg sourcedscalar="bargle"
# whether or not you use `-x` makes no difference for the environment
declare -xga sourcedarray=([0]="foo" [1]="bar")
EOF

sourcefile

echo "Global array: ${globalarray[*]}"
echo "Global scalar: ${globalscalar}"
echo "Sourced array: ${sourcedarray[*]}"
echo "Sourced scalar: ${sourcedscalar}"
Run Code Online (Sandbox Code Playgroud)

  • 这是[变更日志条目](https://git.savannah.gnu.org/cgit/bash.git/tree/CHANGES?h=bash-4.4#n252):bash-4.4-beta -&gt; bash-4.4- rc1:“p。修复了一个错误,该错误导致‘readonly’和‘export’在 shell 函数中使用时创建局部数组变量。” (3认同)