我需要运行一个生成 bash 数组的 bash 脚本,并以某种方式将此数组返回给 bash 调用脚本。返回给调用脚本的结果数组在各个方面都必须与原始数组相同:没有字符(如空格)需要特殊处理。此外,脚本必须是单独的进程,因为我无法在前者的上下文中执行其他脚本。
由于 bash 函数无法在没有 hack 的情况下接受或返回数组,因此这变得更加困难。尽管对数组进行编码/解码可能既复杂又缓慢,但最简单(最少编码)或最快(执行速度)的方法是什么?
给定一个数组——关联与否:
$ typeset -a array
$ array=({1..10})
您的序列化数组将由以下方式给出:
$ typeset -p array
declare -a array='([0]="1" [1]="2" [2]="3" [3]="4" \
[4]="5" [5]="6" [6]="7" [7]="8" [8]="9" [9]="10")'
这将在来和去时都起作用,因为typeset/declare -p name
它为您提供了已声明变量的确切构造命令。
结果是带有声明本身的字符串,您可以从中对数组进行评估——使用 GNU bash 4.2.24 版进行测试:
$ declaration=$(typeset -p array)
$ eval ${declaration}
另一种干净利落的方法是使用 NUL 分隔的流,它的优点是您可以从 bash 以外的语言和工具中读取它。要生成该流:
printf '%s\0' "${your_array[@]}"
...并且,阅读它:
your_array=()
while IFS='' read -r -d '' entry; do
your_array+=( "$entry" )
done
这还具有不需要信任生成数据的代码的优点,就像使用eval
.
对于关联或稀疏数组,可以发出对:
for key in "${!your_array[@]}"; do
printf '%s\0' "$key" "${your_array[$key]}"
done
...并且,对于回读:
declare -A your_array # if associative
while IFS='' read -r -d '' key && IFS='' read -r -d '' value; do
your_array["$key"]="$value"
done