代码之家  ›  专栏  ›  技术社区  ›  Cyker

bash:使用同名的局部变量隐藏全局变量

  •  1
  • Cyker  · 技术社区  · 7 年前

    我希望在函数中使用全局变量,但不希望更改超出函数范围。所以我定义了一个初始化为全局变量值的局部变量。全局变量的名称很好,所以我想在局部变量上使用相同的名称。这在bash中似乎可行,但我不确定这是否是未定义的行为。

    #!/bin/bash
    
    a=3
    echo $a
    foo() {
        local a=$a  ##  defined or undefined?
        a=4
        echo $a
    }
    foo
    echo $a
    

    给出输出:

    3
    4
    3
    
    2 回复  |  直到 7 年前
        1
  •  4
  •   Ondrej K.    7 年前

    扩展发生在分配(早期)之前 documentation states :

    将命令行拆分为单词后,在命令行上执行扩展。

    因此,行为应该是可预测的(和定义的)。在 local a=$a 膨胀时 $a 它仍然是全球性的。命令执行(赋值/声明)发生在后面(当 $A 已被其值替换)。

    但是,我不确定,如果两个变量(取决于作用域)具有相同的名称(即,看起来是同一个变量),这不会让人混淆。因此,我宁愿质疑在编码实践/可读性/导航场地的易用性方面这样做的明智性。

        2
  •  1
  •   Benjamin W.    7 年前

    在bash 5.0中有一个新的shell选项, localvar_inherit ,若要让具有相同名称的局部变量继承前面作用域中具有相同名称的变量的值:

    #!/usr/bin/env bash
    
    shopt -s localvar_inherit
    
    myfunc() {
        local globalvar
        echo "In call: $globalvar"
        globalvar='local'
        echo "In call, after setting: $globalvar"
    }
    
    globalvar='global'
    echo "Before call: $globalvar"
    myfunc
    echo "After call: $globalvar"
    

    具有以下输出:

    Before call: global
    In call: global
    In call, after setting: local
    After call: global
    

    如果没有bash 5.0,则必须像在问题中那样在函数中设置值,并使用相同的结果。

    推荐文章