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

标签 arrays bash macos function scope

考虑以下 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}"

人们会合理地期望在输出中设置所有四个值,但至少对于 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
据我所知:
  • 通过获取文件在函数中创建的标量变量在全局范围内创建
  • 但是通过获取文件在函数中创建的数组变量是在本地范围内创建的,导出它不会改变这一点

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

    最佳答案

    正如评论中指出的那样,在更"new"版本的 bash 中,这不再是问题。对于 4.3 及以下版本,我们发现以下内容:
    首先,分配是否在源脚本中没有任何作用;功能有所作为。但是,单独的功能也不会导致您的问题。只有函数+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}"
    

    关于arrays - 通过在函数内部采购创建的 bash 数组具有局部作用域,但标量是全局的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66845993/

    相关文章:

    javascript - 将对象内的相同 id 连接到一个对象数组

    arrays - 使用 mgo.v2 将新对象插入到 mongodb 文档中的数组属性中

    javascript - 在 Angular js 中使用 ng-repeat 指令在表中显示数组数据

    linux - BASH 中的基本 Shell 脚本

    linux - 使用 bash rsync 远程站点

    python - wx无法在mac上运行

    objective-c - '-(bool)validateToolbarItem:(NSToolbarItem *)theItem' 的类型冲突

    javascript - 使数组上的值匹配更快?

    linux - Shell - 更改文件名而不更改给定路径的扩展名

    bash - 如何创建多行 curl 字符串,变量包含在单引号和双引号中?