为什么空的bash数组长度为1?这让我疯了。任何人都可以解释array3
发生的事情吗?
$ bash
$ echo $BASH_VERSION
4.3.11(1)-release
$ set | egrep '(array1|array2|array3|indirect)'
$ array1=(); echo ${#array1[@]}
0
$ declare -a array2; echo ${#array2[@]}
0
$ indirect=array1; array3=${!indirect}; echo ${#array3[@]}
1
$ echo "what's in here? ->${array3[0]}<-"
what's in here? -><-
$ set | egrep '(array1|array2|array3|indirect)'
array1=()
array3=
indirect=array1
我通过尝试一个独特的appender&#34;对于bash数组的函数,结果在开头时保持了额外的空元素。谢谢你的聆听; - )
答案 0 :(得分:2)
这不符合你的想法:
array1=( )
indirect=array1
array3=${!indirect}
...这不是,而且从来就不是,是创建间接命名数组内容副本的语法。相反,它将空字符串(空array1
中的第一个条目)分配给array3
:
$ declare -p array3
declare -- array3=""
考虑一个不那么令人困惑的例子:
$ array1=( hello cruel world )
$ indirect=array1
$ echo ${!indirect}
hello
...也就是说你间接执行了作业array3=$array1
(将array1
中的第一个元素指定给名为array3
的字符串),不< / strong> array3=( "${array1[@]}" )
(创建一个名为array3
的数组,其内容与数组array1
相同。)
如果您的目标是bash 4.3,那么该语言的新增内容(或者说,最近采用的ksh功能)就是为了这个目的:namevars。
append_if_unique() {
local varname=$1; shift
# create a new global array if our destination doesn't already exist
declare -p "$varname" >/dev/null 2>&1 || declare -g -a "$varname"
# avoid nasty corner cases around locals colliding with destination
if [[ $varname =~ ^(varname|var|value|new_value)$ ]]; then
echo "ERROR: cannot append to a variable named $varname" >&2
return 1
fi
local -n var="$varname"
local value new_value
for new_value; do
for value in "${var[@]}"; do
if [[ $value = "$new_value" ]]; then
continue 2 # skip to next proposed new value
fi
done
var+=( "$new_value" )
done
}
...此后:
append_if_unique myarray "first value" "second value" "first value"
append_if_unique myarray "first value" "third value"
declare -p myarray
......会发出......
declare -a myarray='([0]="first value" [1]="second value" [2]="third value")'
...但是,除非要求保留订单,否则根本不需要花哨的功能。只需使用关联数组:
declare -A myarray
myarray["first value"]=1
myarray["second value"]=1
myarray["third value"]=1
myarray["third value"]=1
...此后:
# iterate over keys with ${!yourarray[@]} to access
for key in "${!myarray[@]}"; do
printf '%s\n' "$key"
done