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[${#arr...@]}]=' is as expected. > > Thanks for the report. The question is what ${#arr...@]} 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 '${#arr...@]}'. But ${!arr...@]} 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 ${#arr...@]} 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 "\${#a...@]} returns: ${#a...@]}" echo "\${!a...@]} returns: ${!a...@]}" [[ -z ${arr} && ${#a...@]} = 1 ]] && echo "DECLARED, BUT EMPTY - needs 2 tests" for x in $str; do arr[${#a...@]}]="$x" echo "\${#a...@]} returns: ${#a...@]}" echo "\${!a...@]} returns: ${!a...@]}" 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 ${#a...@]} returns: 0 ${!a...@]} returns: ${#a...@]} returns: 1 ${!a...@]} returns: 0 ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} returns: 0 1 2 POST FILL: declare -a arr='([0]="a" [1]="b" [2]="c")' PRE FILL: declare -- arr="" ${#a...@]} returns: 1 ${!a...@]} returns: 0 DECLARED, BUT EMPTY - needs 2 tests ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} returns: 0 1 2 ${#a...@]} returns: 4 ${!a...@]} 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="" ${#a...@]} returns: 1 ${!a...@]} returns: 0 DECLARED, BUT EMPTY - needs 2 tests ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} returns: 0 1 2 ${#a...@]} returns: 4 ${!a...@]} 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 ${#a...@]} returns: 0 ${!a...@]} returns: ${#a...@]} returns: 1 ${!a...@]} returns: 0 ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} 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 ${#a...@]} returns: 0 ${!a...@]} returns: ${#a...@]} returns: 1 ${!a...@]} returns: 0 ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} returns: 0 1 2 POST FILL: declare -a arr='([0]="a" [1]="b" [2]="c")' LOCAL VAR in func: PRE FILL: declare -- arr="" ${#a...@]} returns: 1 ${!a...@]} returns: 0 DECLARED, BUT EMPTY - needs 2 tests ${#a...@]} returns: 1 ${!a...@]} returns: 1 ${#a...@]} returns: 1 ${!a...@]} returns: 1 ${#a...@]} returns: 1 ${!a...@]} 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 ${#a...@]} returns: 0 ${!a...@]} returns: ${#a...@]} returns: 1 ${!a...@]} returns: 0 ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} 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 ${#a...@]} returns: 0 ${!a...@]} returns: ${#a...@]} returns: 1 ${!a...@]} returns: 0 ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} returns: 0 1 2 POST FILL: declare -a arr='([0]="a" [1]="b" [2]="c")' LOCAL VAR in func: PRE FILL: declare -- arr="" ${#a...@]} returns: 0 ${!a...@]} returns: 0 ${#a...@]} returns: 1 ${!a...@]} returns: 0 ${#a...@]} returns: 2 ${!a...@]} returns: 0 1 ${#a...@]} returns: 3 ${!a...@]} returns: 0 1 2 POST FILL: declare -a arr='([0]="a" [1]="b" [2]="c")' -------------------------------------------------- Best regards Mart