Bash: Hide global variable using local variable with same name

时间:2019-01-15 18:09:50

标签: bash scope

I'd like to use a global variable in a function but don't want the change to go outside the function. So I defined a local variable initialized to the value of the global variable. The global variable has a great name, so I want to use the same name on the local variable. This seems doable in Bash, but I'm not sure if this is undefined behavior.

#!/bin/bash

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

Gives output:

3
4
3

2 个答案:

答案 0 :(得分:4)

Expansion happen before assignment (early on) as the documentation states:

Expansion is performed on the command line after it has been split into words.

So the behavior should be predictable (and defined). In local a=$a when expanding $a it's still the global one. The command execution (assignment/declaration) happens later (when $a has already been replaced by its value).

However I am not sure this would not get confusing to have essentially two different variables (scope dependent) with the same name (i.e. appearing to be the one and same). So, I'd rather question wisdom of doing so on coding practices / readability / ease of navigation grounds.

答案 1 :(得分:1)

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,则必须像在问题中一样在函数中设置值,并得到相同的结果。

相关问题