当在函数体内声明时,关联数组在默认情况下似乎是本地的,它们应该是全局的。以下代码
#!/bin/bash
f() {
declare -A map
map[x]=a
map[y]=b
}
f
echo x: ${map[x]} y: ${map[y]}
产生输出:
x: y:
虽然这个
#!/bin/bash
declare -A map
f() {
map[x]=a
map[y]=b
}
f
echo x: ${map[x]} y: ${map[y]}
产生输出:
x: a y: b
是否可以在函数中声明全局关联数组? 或者可以使用哪种解决方法?
答案 0 :(得分:23)
来自:Greg Wooledge
发送时间:2011年8月23日星期二06:53:27 -0700
主题:回复:YAQAGV(关于全局变量的另一个问题)bash 4.2添加“declare -g”以从a中创建全局变量 功能
谢谢格雷格!但Debian Squeeze仍有Bash 4.1.5
答案 1 :(得分:7)
您已使用declare -g回答了自己的问题。关于bash版本的解决方法< 4.2是在函数外声明数组。
f() {
map[y] = foo
}
declare -A map
foo
echo "${map[y]}"
答案 2 :(得分:5)
很好,4.2增加了“declare -g”,但它对于关联数组来说是错误的,所以它还没有(还)回答这个问题。这是我的错误报告,切特确认下次发布时有一个修复程序。
http://lists.gnu.org/archive/html/bug-bash/2013-09/msg00025.html
但我偶然发现了一种解决方法,而不是声明数组并同时为其分配初始值,首先声明数组然后执行赋值。也就是说,不要这样做:
declare -gA a=([x]=1 [y]=2)
但请改为:
declare -gA a; a=([x]=1 [y]=2)
答案 3 :(得分:2)
此示例在bash中的函数内部声明了一个全局关联数组变量。
set -euf +x -o pipefail # There is no place for implicit errors in this script.
function init_arrays(){
# FYI. Multiple array declarations are not a problem. You can invoke it multiple times.
# The "-gA" switch is the trick for the global array declaration inside a function.
declare -gA my_var
}
function do_work(){
init_arrays
my_var[$1]=OPPA
}
do_work aa
echo ${my_var[aa]}
echo It is expected to get OPPA value printed above
在GNU bash 4.4版上进行了测试...
重要说明。
declare -A
命令doesn't actually create an associative array立即;它只是在变量名称上设置一个属性,该属性使您可以将其作为关联数组分配给该名称。直到第一个赋值(!!!),数组本身才存在。
(抱歉,我想在此线程中看到一个完整的工作示例。)
答案 4 :(得分:0)
对于那些坚持使用Bash版本<4.2且对建议的变通方法不满意的人,我分享了我的全局关联数组的自定义实现。它没有bash关联数组的全部功能,因此您需要注意数组索引中的特殊字符,但要做好工作。
get_array(){
local arr_name="$1"
local arr_key="$2"
arr_namekey_var="ASSOCARRAY__${arr_name}__${arr_key}"
echo "${!arr_namekey_var:=}"
}
set_array(){
local arr_name="$1"
local arr_key="$2"
local arr_value="$3"
arr_namekey_var="ASSOCARRAY__${arr_name}__${arr_key}"
if [[ -z "${arr_value}" ]]; then
eval ${arr_namekey_var}=
else
printf -v "${arr_namekey_var}" "${arr_value}"
fi
}
一些注意事项:
__
作为分隔符可以被恶意或粗心大意的黑客入侵-为了安全起见,仅使用字母数字值,仅在数组名称和键中使用单下划线值。当然,可以根据应用程序和开发人员的需求来调整内部变量的组成(分隔符,前缀,后缀...)。