bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: building arrays from non array variables using 'array[${#array[@]}]=


From: Mart Frauenlob
Subject: Re: building arrays from non array variables using 'array[${#array[@]}]='
Date: Mon, 25 Jan 2010 12:58:02 +0100
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.7) Gecko/20100111 Thunderbird/3.0.1

On 24.01.2010 21:19, Chet Ramey wrote:
> On 1/24/10 5:13 AM, Mart Frauenlob wrote:
>> Hello,
>>
>> I'd like to ask, if the behavior of indexed array assignment using the
>> form: 'array[${#array[@]}]=' is as expected.
> 
> Thanks for the report.  The question is what ${#array[@]} should return
> when it refers to a scalar variable that has not been assigned a value.
> Previous versions of bash returned 1, not checking whether or not the
> variable is set; the right answer is 0 if the variable is not set and 1
> otherwise.
> 
> Any official change will probably wait until bash-4.2.  I have attached a
> patch to evaluate, though.
> 
> Chet

Hello Chet,

thank you for your quick reply and patch :)
As i came up with this i have to go further ;) ,so i installed bash
4.1.2 and your new patch and ran tests again with it and 3.1.17, 4.0.35
versions.
Patch seems to be working for return values of '${#array[@]}'.
But ${!array[@]} returns 0 on the declared but unassigned local variable
- which i think should be the NULL string.

What worries me, is that v4.0.35 behaves weird with a local variable
declared, as ${#array[@]} always returns 1 inside the fill() loop.

Also i noticed, that from bash 4 it looks like the declare builtin
reacts differently. `declare -p var' on a globally declared but
unassigned variable returns false, but for the same thing as a local
variable it returns: `declare -- var=""' (with true as exit status of
course).

Testing script and output follows:

#------------------------------------------------------------------
# TEST SCRIPT - non_arr_var_arr_assign
#------------------------------------------------------------------
fill() {
echo "PRE FILL:"
declare -p arr
echo "\${#arr[@]} returns: ${#arr[@]}"
echo "\${!arr[@]} returns: ${!arr[@]}"
[[ -z ${arr} && ${#arr[@]} = 1 ]] && echo "DECLARED, BUT EMPTY - needs 2
tests"
for x in $str; do
    arr[${#arr[@]}]="$x"
    echo "\${#arr[@]} returns: ${#arr[@]}"
    echo "\${!arr[@]} returns: ${!arr[@]}"
done
echo "POST FILL:"
declare -p arr
echo
}

func() {
echo "LOCAL VAR in ${FUNCNAME}:"
local arr
fill
}

str="a b c"

fill
unset arr

declare arr
fill
unset arr

func

#------------------------------------------------------------------
# TEST OUTPUT
#------------------------------------------------------------------
bash 3.1:
eris:/tmp# /bin/bash non_arr_var_arr_assign
PRE FILL:
non_arr_var_arr_assign: line 6: declare: arr: not found
${#arr[@]} returns: 0
${!arr[@]} returns:
${#arr[@]} returns: 1
${!arr[@]} returns: 0
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
POST FILL:
declare -a arr='([0]="a" [1]="b" [2]="c")'

PRE FILL:
declare -- arr=""
${#arr[@]} returns: 1
${!arr[@]} returns: 0
DECLARED, BUT EMPTY - needs 2 tests
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
${#arr[@]} returns: 4
${!arr[@]} returns: 0 1 2 3
POST FILL:
declare -a arr='([0]="" [1]="a" [2]="b" [3]="c")'

LOCAL VAR in func:
PRE FILL:
declare -- arr=""
${#arr[@]} returns: 1
${!arr[@]} returns: 0
DECLARED, BUT EMPTY - needs 2 tests
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
${#arr[@]} returns: 4
${!arr[@]} returns: 0 1 2 3
POST FILL:
declare -a arr='([0]="" [1]="a" [2]="b" [3]="c")'
--------------------------------------------------

bash4.0.35:
eris:/tmp# /usr/local/bin/bash4 non_arr_var_arr_assign
PRE FILL:
non_arr_var_arr_assign: line 6: declare: arr: not found
${#arr[@]} returns: 0
${!arr[@]} returns:
${#arr[@]} returns: 1
${!arr[@]} returns: 0
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
POST FILL:
declare -a arr='([0]="a" [1]="b" [2]="c")'

PRE FILL:
non_arr_var_arr_assign: line 6: declare: arr: not found
${#arr[@]} returns: 0
${!arr[@]} returns:
${#arr[@]} returns: 1
${!arr[@]} returns: 0
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
POST FILL:
declare -a arr='([0]="a" [1]="b" [2]="c")'

LOCAL VAR in func:
PRE FILL:
declare -- arr=""
${#arr[@]} returns: 1
${!arr[@]} returns: 0
DECLARED, BUT EMPTY - needs 2 tests
${#arr[@]} returns: 1
${!arr[@]} returns: 1
${#arr[@]} returns: 1
${!arr[@]} returns: 1
${#arr[@]} returns: 1
${!arr[@]} returns: 1
POST FILL:
declare -a arr='([1]="c")'
--------------------------------------------------

bash4.1.2 (with new patch):
eris:/tmp# /usr/local/bash-4.1/bin/bash non_arr_var_arr_assign
PRE FILL:
non_arr_var_arr_assign: line 6: declare: arr: not found
${#arr[@]} returns: 0
${!arr[@]} returns:
${#arr[@]} returns: 1
${!arr[@]} returns: 0
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
POST FILL:
declare -a arr='([0]="a" [1]="b" [2]="c")'

PRE FILL:
non_arr_var_arr_assign: line 6: declare: arr: not found
${#arr[@]} returns: 0
${!arr[@]} returns:
${#arr[@]} returns: 1
${!arr[@]} returns: 0
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
POST FILL:
declare -a arr='([0]="a" [1]="b" [2]="c")'

LOCAL VAR in func:
PRE FILL:
declare -- arr=""
${#arr[@]} returns: 0
${!arr[@]} returns: 0
${#arr[@]} returns: 1
${!arr[@]} returns: 0
${#arr[@]} returns: 2
${!arr[@]} returns: 0 1
${#arr[@]} returns: 3
${!arr[@]} returns: 0 1 2
POST FILL:
declare -a arr='([0]="a" [1]="b" [2]="c")'
--------------------------------------------------


Best regards

Mart


reply via email to

[Prev in Thread] Current Thread [Next in Thread]