首页 > 解决方案 > 分配由数组中的变量名称提供的系统变量

问题描述

有一堆变量可以赋值。我可以通过复制粘贴同一段代码以愚蠢的方式做到这一点,然后更改不同的部分。例如,我想做以下事情: export country="US" export city="LA"

带有用户输入界面的愚蠢方法是:

printf "\nPlease assign country$ \n" ;  
if [[ $country == nil ]] ; then
    printf "Current value is nil\n"
else
    printf "Current value is: $country\n"
fi ;
printf "country: " ;
read -e -i $country country_
export country=$country_

而对于城市,我只是用“城市”搜索替换“国家”并通过代码,这很愚蠢,但有效。现在,我想提高代码的可读性和可维护性,将变量名放在一个列表中,然后遍历这个列表。谷歌搜索后的半成品代码是:

declare -a var_list=("country" "city")
for var in ${var_list[*]}
    do
        printf "\nPlease assign $var \n" ;  
        if [[ ${!var} == nil ]] ; then
            printf "Current value is nil\n"
        else
            printf "Current value is: ${!var}\n"
        fi ;
        printf "${bold}$var: ${normal}" ;
        read -e -i ${!var} {$var_}
        export $var={$var_}
    done

以下 2 行代码仍然无法正确执行我希望他们执行的操作:

read -e -i ${!var} {$var_}
export $var={$var_}

我想得到一些帮助。

标签: bashshell

解决方案


从中创建一个函数并将变量名传递给它:

get() {
        # descriptive variable names
        local var previousvalue
        var="$1"
        previousvalue="${!1}"

        # superfluous, servers as a documentation
        # The string "$1" should be a global variable
        declare -g "$var"

        # Asking the real questions:
        printf "\nPlease assign $var \n"
        printf "Current value is '$previousvalue'\n"
        read -e -p "$1: " -i "$previousvalue" "$var"
}


declare -a var_list=("country" "city")
for i in "${var_list[@]}"; do           # or just `for i in country city; do`
        get "$i"
done

echo
echo "country=$country"
echo "city=$city"

示例执行:

Please assign country 
Current value is ''
country: Poland

Please assign city 
Current value is ''
city: Warsaw

country=Poland
city=Warsaw

笔记:

  • 不要使用for var in ${var_list[*]},它会不正确地处理其中带有空格的数组元素。做for var in "${var_list[@]}"。将"${...[@]}"正确引用并传递所有变量。
  • export $var={$var_}行将扩展后命名的变量导出到由变量和扩展$var组成的字符串。我猜你不想包含在值中。我猜你想写或者-必须在之后。{var_}{ }"${var}_""${var_}"{$

推荐阅读