1

I writte the following script

load function should set the array disk[a]=1 and disk[b]=2 and so on

Then the function out should print the array ${disk[a]} , and ${disk[b]} , and so on

But what we get from function out is always the number 4

Instead, I want to get the following:

1
2
3
4

What is wrong here ?

How to fix it so function out will print:

1
2
3
4

the script:

#!/bin/bash

function load
{
  counter=1
  for input in a b c d
  do
    disk[$input]=$counter
    let counter=$counter+1
    echo ${disk[$input]}
  done
}


function out
{
  counter=1
  for input in  a b c d
  do
    echo ${disk[$input]}
    let counter=$counter+1
  done
}

echo "run function load"
load
echo "run function out"
out

the output:

./test
run function load
1
2
3
4
run function out
4
4
4
4
5

Bash arrays are indexed arrays by default:

An indexed array is created automatically if any variable is assigned to using the syntax name[subscript]=value

... but you are using letters as the index, so you probably want an associative array, which means you need an:

declare -A disk

before calling the functions.

  • what actually declare -A do? – yael Nov 1 '18 at 18:00
  • 1
    @yael, it declares an associative array – Jeff Schaller Nov 1 '18 at 18:00
6

Look at what happens to the array when you initialize it:

$ i=0; for k in a b c d; do A[$k]=$((i++)); done; declare -p A
declare -a A=([0]="3")

Only one element is present, and it has the index zero.

By default, arrays are indexed by numbers, and the numerical values of the indices you used happened to be all zero. Actually, in an arithmetic context, like the subscript of a regular array, a string is taken as the name of a variable, and the value of that variable is used. So, if we set a, b... to numbers, then we get something different:

$ a=123; b=456; c=789; d=999; i=0;
$ for k in a b c d; do A[$k]=$((i++)); done;
$ declare -p A
declare -a A=([123]="0" [456]="1" [789]="2" [999]="3")

To actually use the strings themselves as indices, declare the array as an associative array first with declare -A arrayname or typeset -A arrayname:

$ unset A; declare -A A; i=0;
$ for k in a b c d; do A[$k]=$((i++)); done; declare -p A
declare -A A=([a]="0" [b]="1" [c]="2" [d]="3" )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.