【问题标题】:Bash : Use a variable as an associative array nameBash :使用变量作为关联数组名称
【发布时间】:2023-03-27 18:13:01
【问题描述】:

我正在编写一个 Bash 脚本来简化从我们的主站点到多个机构的文件复制。 在此脚本中,我尝试使用变量作为关联数组名称,但出现错误,代码如下:

#!/bin/bash

declare -A GROUP1
declare -A GROUP2
declare -A GROUP3
declare -A ARRAY

GROUP1["SITE1"]="x.x.x.x"
GROUP1["SITE2"]="y.y.y.y"
GROUP1["SITE3"]="z.z.z.z"

GROUP2["SITE1"]="1.1.1.1"
GROUP2["SITE2"]="2.2.2.2"
GROUP2["SITE3"]="3.3.3.3"

GROUP2["SITE1"]="a.a.a.a"
GROUP2["SITE2"]="b.b.b.b"
GROUP2["SITE3"]="c.c.c.c"

read -p "Choose a group of sites : " group

case $group in
    1 ) DEST="GROUP1" ;;
    2 ) DEST="GROUP2" ;;
    3 ) DEST="GROUP3" ;;
esac

eval "ARRAY=(\${$DEST[@]})"

for elem in "${!ARRAY[@]}"
do
   echo $elem
   echo ${ARRAY[$elem]}
done

这是错误:

./test: line28: TAB : 3.3.3.3 : must use subscript when assigning associative array
./test: line28: TAB : 2.2.2.2 : must use subscript when assigning associative array
./test: line28: TAB : 1.1.1.1 : must use subscript when assigning associative array

我正在尝试做的事情可能吗? 提前致谢。

【问题讨论】:

    标签: arrays bash associative


    【解决方案1】:

    这是可能的,但这并不容易,除非你有bash v4.3。在 4.3 中,您可以使用“nameref”:

    declare -A GROUP1
    declare -A GROUP2
    declare -A GROUP3
    
    GROUP1["SITE1"]="x.x.x.x"
    #...
    
    # Yuk. Use command-line options, not stdin
    read -p "Choose a group of sites : " group
    
    for g in GROUP1 GROUP2 GROUP3; do if [[ $group == $g ]]; then
    
      # Here's the nameref: After this executes, ARRAY is an alias for
      # the indicated variable.
      declare -n ARRAY=$group
      break
    
    fi
    
    ### This is documented but might not work depending on bash version
    ### Instead you could test for existence of a known key:
    ###    if [[ ! -v ${ARRAY[SITE1]} ]]; then
    if [[ ! -R ARRAY ]]; then
     echo "No such group" >> /dev/stderr; exit 1
    fi
    

    好的,您可能还没有 bash 4.3,但在未来,以上内容对某人有用。因此,如果没有它,您可以遵循您建议的策略,即复制指示的关联数组。如果阵列不大,那还不错。为此,请使用上述内容,但将 nameref 行 (declare -n ARRAY=$group) 替换为以下内容:

    defn=$(declare -p $group)
    eval "${defn/$group/ARRAY}"
    unset defn
    

    在这种情况下,您可以使用替代测试来获得成功。


    注意:对于bash 变量名使用全部大写确实不是一个好主意。惯例是系统生成的环境变量和 shell 内置变量使用全部大写。用户变量应小写,以免与这些预定义变量发生冲突。

    【讨论】:

    • 感谢您的回答 rici。我不记得不对用户变量使用大写字母。明天我会试试你的建议。
    猜你喜欢
    • 1970-01-01
    • 2012-04-03
    • 1970-01-01
    • 2012-05-08
    • 1970-01-01
    • 2022-07-21
    • 2015-04-13
    • 2016-04-04
    • 1970-01-01
    相关资源
    最近更新 更多