在彻底搜索了一种在bash中创建关联数组的方法后,我发现它declare -A array可以解决这个问题.但问题是,它仅适用于bash版本4,服务器在我们系统中的bash版本是3.2.16.
如何在bash 3中实现某种类似关联数组的hack?这些值将传递给类似的脚本
ARG=array[key];
./script.sh ${ARG}
Run Code Online (Sandbox Code Playgroud)
编辑:我知道我可以在awk或其他工具中执行此操作,但我正在尝试解决的方案需要严格的bash.
Gil*_*il' 30
Bash 3没有关联数组,因此您将不得不使用其他语言功能.请注意,即使在bash 4下,您编写的代码也没有按照您的声明执行操作:./script.sh ${ARG}不会将关联数组传递给子脚本,因为${ARG}当ARG关联数组时会扩展为空.您无法将关联数组传递给子进程,无论如何都需要对其进行编码.
您需要在父脚本和子脚本之间定义一些参数传递协议.一个常见的方法是在表单中传递参数key=value.这假定该字符=不出现在键中.
您还需要弄清楚如何在父脚本和子脚本中表示关联数组.他们不需要使用相同的表示.
表示关联数组的常用方法是为每个元素使用单独的变量,并使用通用的命名前缀.这要求密钥名称仅由ASCII字母(任何一种情况),数字和下划线组成.例如,代替${myarray[key]},写${myarray__key}.如果在运行时确定密钥,则首先需要进行一轮扩展:而不是${myarray[$key]}写入
n=myarray__${key}; echo ${!n}
Run Code Online (Sandbox Code Playgroud)
对于作业,请使用printf -v.请注意使用指定值的%s格式printf.不要写,因为那将printf -v "myarray__${key}" %s "$value"$value作为一种格式对待并%在其上执行printf 扩展.
printf -v "myarray__${key}" %s "$value"
Run Code Online (Sandbox Code Playgroud)
如果需要将带有这样表示的关联数组传递给带有key=value参数表示的子进程,则可以使用${!myarray__*}枚举名称以其开头的所有变量myarray__.
args=()
for k in ${!myarray__*}; do
n=$k
args+=("$k=${!n}")
done
Run Code Online (Sandbox Code Playgroud)
在子进程中,要将表单的参数转换为key=value带有前缀的单独变量:
for x; do
if [[ $x != *=* ]]; then echo 1>&2 "KEY=VALUE expected, but got $x"; exit 120; fi
printf -v "myarray__${x%%=*}" %s "${x#*=}"
done
Run Code Online (Sandbox Code Playgroud)
顺便问一下,你确定这是你需要的吗?您可能希望在子shell中运行子脚本,而不是从另一个bash脚本调用bash脚本.这样它就会继承父母的所有变量.
以下是使用参数扩展的bash 3及更早版本中关联数组的另一篇文章/解释:https:
//stackoverflow.com/a/4444841
吉尔斯的方法有一个很好的if说法,可以捕捉分隔符问题,消除奇怪的输入......等等.用那个.
如果您对参数扩展有点熟悉:http:
//www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html
在您的场景中使用[如上所述:发送到脚本]:脚本1:
sending_array.sh
# A pretend Python dictionary with bash 3
ARRAY=( "cow:moo"
"dinosaur:roar"
"bird:chirp"
"bash:rock" )
bash ./receive_arr.sh "${ARRAY[@]}"
Run Code Online (Sandbox Code Playgroud)
脚本2: receive_arr.sh
argAry1=("$@")
function process_arr () {
declare -a hash=("${!1}")
for animal in "${hash[@]}"; do
echo "Key: ${animal%%:*}"
echo "Value: ${animal#*:}"
done
}
process_arr argAry1[@]
exit 0
Run Code Online (Sandbox Code Playgroud)
方法2,获取第二个脚本:脚本1:
sending_array.sh
source ./receive_arr.sh
# A pretend Python dictionary with bash 3
ARRAY=( "cow:moo"
"dinosaur:roar"
"bird:chirp"
"bash:rock" )
process_arr ARRAY[@]
Run Code Online (Sandbox Code Playgroud)
脚本2: receive_arr.sh
function process_arr () {
declare -a hash=("${!1}")
for animal in "${hash[@]}"; do
echo "Key: ${animal%%:*}"
echo "Value: ${animal#*:}"
done
}
Run Code Online (Sandbox Code Playgroud)
参考:
在bash中将数组作为参数传递
如果您不想处理大量变量,或者键只是无效的变量标识符,并且您的数组保证少于 256 项,则可以滥用函数返回值。此解决方案不需要任何子shell,因为该值可以作为变量随时可用,也不需要任何迭代,因此性能会大打折扣。它也非常易读,几乎就像 Bash 4 版本。
这是最基本的版本:
hash_index() {
case $1 in
'foo') return 0;;
'bar') return 1;;
'baz') return 2;;
esac
}
hash_vals=("foo_val"
"bar_val"
"baz_val");
hash_index "foo"
echo ${hash_vals[$?]}
Run Code Online (Sandbox Code Playgroud)
此答案中的更多详细信息和变体
| 归档时间: |
|
| 查看次数: |
26575 次 |
| 最近记录: |