0

I am trying to get the user input a first time with read and get the input into the n2 variable, and then when the loop restarts ask the same read question but this time store the answer in the variable n3 and have the n# variable increment every time the loop restarts.

function addition(){
    read -ep 'How many numbers in the equation?: ' amount

    if [ $amount -ge 2 ]
        then
            read -ep 'First number of the addition?: ' n1
            until [ $count = $amount ]
            do
                number=n$((inc++)) 
                read -ep 'Next number for the addition?: ' n2
            done
        else
            echo "Invalid amount. Must be at minimum 2"
    fi
}
3
  • It is possible, but why don't you use an array instead? Commented Feb 2, 2022 at 4:02
  • Well because a array will have a limit to its size and I dont rly want a limit. I would like the limit to be set by the user input instead. Unless there is a way to make a dynamic array that would set itself depending on the user input? Commented Feb 2, 2022 at 13:47
  • Unlike C, the array size of bash is virtually limitless, although there may be some eventual limitation depending on the hardware. You don't even have to enter the maximum size of the array. The array automatically grows each time you append new elements. If you are interested in the solution using an array, I'll post one. Commented Feb 2, 2022 at 22:05

1 Answer 1

3

If your bash is recent enough you can use namerefs:

function foo {
  for (( i = 1; i <= 3; i++ )); do
    local -n number="n$i"
    number="$i"
  done
  printf '%s %s %s\n' "$n1" "$n2" "$n3" 
}

Demo:

$ foo
1 2 3

If you want to export the nX variables to the global scope just add the g attribute to the local declaration:

local -ng number="n$i"

And then:

$ foo
1 2 3
$ echo "$n1 $n2 $n3"
1 2 3

Note that a bash array doesn't have a limit to its size (apart the physical limit of the available computer memory):

function foo {
  local -ag n=()
  for (( i = 1; i <= $1; i++ )); do
    n+=("$i")
  done
}

And:

$ foo 5
$ printf '%s\n' "${n[*]}"
1 2 3 4 5
$ for (( i=0; i<${#n[@]}; i++ )); do printf '%s ' "${n[i]}"; done; printf '\n'
1 2 3 4 5 
$ for val in "${n[@]}"; do printf '%s ' "$val"; done; printf '\n'
1 2 3 4 5 

We could even mix the two approaches and pass the name of the array as first argument:

function foo {
  unset n
  unset -n n
  local -ng n=$1
  for (( i = 1; i <= $2; i++ )); do
    n+=("$i")
  done
}

And:

$ foo myArray 7
$ printf '%s\n' "${myArray[*]}"
1 2 3 4 5 6 7
Sign up to request clarification or add additional context in comments.

3 Comments

How flexible is that solution? Becauae I want it to go as high as the user input is. So if the user input is 5 id like for the variable to go up to n5 for exemple which is why I dont use a array because I dont want to force a limit.
Well, this was just an example of use of namerefs. Of course it is flexible. But you'll have to adapt to your needs. Instead of fixed loop bounds use user-provided inputs if you need to. In your own code try to replace number=n$((inc++)) by local -ng number=n$((inc++)) and n2 by number and see. And, by the way, arrays are not limited. If you declare an empty array (local -ag n) you can append to it with n+=("$foobar"). No limit apart the available memory on your computer.
I added an example of use of an indexed array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.