首页 > 解决方案 > 将数组从一个 shell 脚本传递和解析到另一个

问题描述

由于脚本中有 9 个参数的限制,我的目标是将大约 30 个捆绑在数组中的字符串从调用脚本 (scriptA) 传递到被调用脚本 (scriptB)。

我的 scriptA 看起来像这样......

#!/bin/bash
declare -a arr=( ab "c d" 123 "string with spaces" 456 )
. ./scriptB.sh "Task Name" "${arr[@]}"

我的 scriptB 看起来像这样......

#!/bin/bash
arg1="$1"
shift
arg2=("$@")
read -a arr1 <<< "$@"
j=0
for i in "${arr1[@]}"; do
#echo ${arr1[j]}
((j++))
case "$j" in
"1")
param1="${i//(}"
echo "$j=$param1"
;;
"2")
param2="${i}"
echo "$j=$param2"
;;
"3")
param3="${i}"
echo "$j=$param3"
;;
"4")
param4="${i}"
echo "$j=$param4"
;;
"5")
param5="${i//)}"
echo "$j=$param5"
;;
esac
done

输出:

1=ab
2=c
3=d
4=123
5=string

问题:

1. I see parenthesis ( and ) gets added to the string which I have to strip them out
2. I see an array element (with spaces) though quoted under double quotes get to interpreted as separate elements by spaces.

标签: arraysbashparameters

解决方案


read -a arr1 <<< "$@"

是错的。这里"$@"等于"$*",然后read将在空格(空格、制表符和换行符)上拆分输入,并解释\斜杠并将结果分配给 array arr1。记得使用read -r.

做:

arr1=("$@")

分配给一个数组。然后你可以打印:

for ((i=1;i<${#arr1};++i)); do 
   printf "%d=%s\n" "$i" "${arr1[$i]}"
done

在脚本中的 9 个参数中,我的目标是从调用脚本 (scriptA) 传递捆绑在数组中的大约 30 个字符串

好的。但是"${arr[@]}"无论如何都要传递多个参数。如果要将数组作为字符串传递,请将其作为字符串传递(注意eval 是 evil):

arr=( ab "c d" 123 "string with spaces" 456 )
./scriptB.sh "Task Name" "$(declare -p arr)"
# Then inside scriptB.sh, re-evaulate parameter 2:
eval "$2" # assigns to arr

请注意,scriptB.sh在您的示例中,因此传递参数.... 无论如何都没有意义。

我看到一个数组元素(带空格)虽然用双引号引用,但被空格解释为单独的元素

是的,因为您使用 解释了内容read,它将输入拆分为 中的字符IFS,默认情况下设置为空格、制表符和换行符。您可以在单独的行上打印参数并相应地更改 IFS:

IFS=$'\n' read -r -a arr1 < <(printf "%s\n" "$@")

甚至使用以零结尾的字符串:

mapfile -t -d '' arr1 < <(printf "%s\0" "$@")

但那些只是花哨和无用的写作方式arr1=("$@")

请注意,在您的代码中,arg2是一个数组。


推荐阅读