bash:将关联数组作为参数传递给另一个脚本

时间:2020-09-25 12:12:48

标签: bash associative-array

我希望能够做到:

Script1.sh

declare -A map=(
  ['A']=1
  ['B']=2
  ['C']=3
  ['D']=4
)

sh script2.sh ???

Script2.sh

params = ...
echo ${params['A']}

即,通过键访问参数。我已经看到了有关普通数组的相关问题,而答案是将数组传递为:

sh script2.sh "${AR[@]}"

我相信可以翻译成:

sh script2.sh  "${map[0]}" "${map[1]}" "${map[2]}"

但是,我只能根据其顺序访问元素。

是否有达到我想要的目的的聪明技巧?也许是通过"A=1" "B=2" "C=3" "D=4"传递并让script2.sh解析它们的东西?还是有更整洁的解决方案?

2 个答案:

答案 0 :(得分:3)

如果您只是从script2.sh内部调用script1.sh的{​​em} ,那么您要做的所有事情(如@ markp-fuso所指出的)就是源script2.sh它将在当前上下文中运行,并且已加载所有数据。

如果您确实希望将其放在命令行中,则将其作为key=val传递,并将代码放入script2.sh中,以检查该格式的每个参数并将它们设置在关联数组中。

declare -A map=()
for arg in "$@"
do if [[ "$arg" =~ ^[A-Z]=[0-9]$ ]] # more complex k/v will get ugly
   then map[${arg/=?}]=${arg/?=}    # as will the assignment w/o eval
   fi
done
# And finally, just to see what got loaded -
declare -p map

$: script2.sh C=3 A=1
declare -A map=([A]="1" [C]="3" )
如上所述,一组可能更复杂的键名和/或值将需要适当更复杂的测试以及分配逻辑。显然,除了最简单的情况以外,这都会很快成为问题。

甚至更好,设置一个完整的getopts循环,并为您的args传递适当的指示符。这需要更多的设计和更多的实现,但这就是获得更多功能所需的条件。

答案 1 :(得分:2)

假设:

  • 该数组是传递给script2的唯一项(可以放宽,但可能需要向script2添加一些选项标志处理)
  • 数组名称将始终为map(可能会使其动态化,但这将是另一天)
  • 数组索引和值不包含任何特殊/控制字符(例如换行符),否则将命令行上的数组结构传递给script2会变得非常复杂(可能有一些变通方法)场景)

一些基本组件:

名为map的数组:

$ declare -A map=(
  ['A']=1
  ['B']=2
  ['C']=3
  ['D']=4
)

使用typeset生成命令以(重新)产生数组map的内容:

$ typeset -p map
declare -A map=([A]="1" [B]="2" [C]="3" [D]="4" )

从这里我们可以将typeset的输出传递到script2,然后让script2 eval对输入进行求值,例如:

$ cat script1
echo "in script1"
declare -A map=(
  ['A']=1
  ['B']=2
  ['C']=3
  ['D']=4
)
./script2 $(typeset -p map)

$ cat script2
echo "in script2"
echo " \$@ = $@"
eval "$@"
for i in "${!map[@]}"
do
        echo "${i} : ${map[${i}]}"
done

运行script1会生成:

$ ./script1
in script1
in script2
 $@ = declare -A map=([A]="1" [B]="2" [C]="3" [D]="4" )
A : 1
B : 2
C : 3
D : 4

我知道,我知道,我知道... eval ==邪恶。我将不得不考虑替换eval……也可以提出建议。

相关问题