【问题标题】:Bash how to parse asscoiative array from argument?Bash如何从参数解析关联数组?
【发布时间】:2021-03-08 23:11:44
【问题描述】:

我正在尝试将字符串读入关联数组。

字符串被正确转义并读入 .sh 文件:

./myScript.sh "[\"el1\"]=\"val1\" [\"el2\"]=\"val2\""

在脚本中

#!/bin/bash -e
declare -A myArr=( "${1}" ) #it doesn't work either with or without quotes

我得到的是:

line 2: myArr: "${1}": must use subscript when assigning associative array

谷歌搜索错误只会导致“您的数组格式不正确”的结果。

【问题讨论】:

  • 请尝试:declare -A "myArr=( ${1} )"
  • 与使用eval 一样,在处理复杂输入时可能会产生代码注入或其他错误。
  • 你可以接受./myScript.sh el1 val1 el2 val2之类的东西吗?

标签: bash associative-array


【解决方案1】:

您可以从一系列变量输入中读取键/值对:

$ cat > example.bash <<'EOF'
#!/usr/bin/env bash

declare -A key_values
while true
do
    key_values+=(["$1"]="$2")
    shift 2
    if [[ $# -eq 0 ]]
    then
        break
    fi
done

for key in "${!key_values[@]}"
do
    echo "${key} = ${key_values[$key]}"
done
EOF
$ chmod u+x example.bash
$ ./example.bash el1 val1 el2 val2
el2 = val2
el1 = val1

无论键和值是什么,这都应该是安全的。

【讨论】:

    【解决方案2】:

    不要关心正确的双重转义,而是在调用方设置变量,并使用 bash declare -p。这样,您将始终得到正确转义的字符串。

    declare -A temp=([el1]=val1 [el2]=val2)
    ./script.sh "$(declare -p temp)"
    

    然后做:

    # ./script.sh
    # a safer version of `eval "$1"`
    declare -A myarr="${1#*=}"
    

    【讨论】:

      【解决方案3】:

      解决方案:

      ./test.sh "( [\"el1\"]=\"val1\" [\"el2\"]=\"val2\" )"
      

      在脚本中:

      #!/bin/bash -e
      
      declare -A myArr="${1}"
      declare -p myArr
      
      for i in "${!myArr[@]}"
      do
        echo "key  : $i"
        echo "value: ${myArr[$i]}"
      done
      

      返回:

      > ./test.sh "( [\"el1\"]=\"val1\" [\"el2\"]=\"val2\" )"
      declare -A myArr=([el2]="val2" [el1]="val1" )
      key  : el2
      value: val2
      key  : el1
      value: val1
      

      我无法解释为什么会这样,或者为什么顺序会改变。

      Test it yourself here

      【讨论】:

      • 这在我的测试中不起作用;它创建一个包含整个参数作为文字字符串的单个数组元素(由“0”索引)。在末尾添加declare -p myArr,看看实际发生了什么。
      • @GordonDavisson 它非常适合我 - 你的问题是什么?也改进了答案,你可以看到declare -p myArr的输出
      • 啊,我明白了,我在测试它时没有在参数中提供外括号(我只是从原始问题中复制了参数格式)。有了括号,它也适用于我。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-11
      • 1970-01-01
      • 2019-03-01
      • 2015-06-30
      • 2012-01-19
      相关资源
      最近更新 更多