0

I'm trying to write a recursive bash function for Fibonacci sequence. So far I have a code like below:

#!/bin/bash
Fibo() {
   case $1 in
     0) echo 0;;
     1) echo 1;;
     *) echo $[$[$Fibo $[$1-1]]+$[$Fibo $[$1-2]]] ;;
   esac
}

for (( i=0; i<=$1; i++ )); do
   Fibo $i
done

Here's a sample output:

0
1
1
3
5
7
9
11

Of course, it should be 0 1 1 2 3 5 8 13 ...

I tried to write it down in the paper and in my opinion it should work. My code understanding:

Fibo 0 -> = 0
Fibo 1 -> = 1
Fibo 2 -> Fibo 1 + Fibo 0 = 1 + 0 = 1
Fibo 3 -> Fibo 2 + Fibo 1 = 1 + 1 = 2
Fibo 4 -> Fibo 3 + Fibo 2 = 2 + 1 = 3
Fibo 5 -> Fibo 4 + Fibo 3 = 3 + 2 = 5
etc...

What the code "is doing":

Fibo 0 -> = 0
Fibo 1 -> = 1
Fibo 2 -> = 1 + 0 = 1
Fibo 3 -> = 3 (??)
Fibo 4 -> = 5 (this is probably 3+1+1)
Fibo 5 -> = 7 (this is probably once again 5+1+1)
Fibo 6 -> = 9 (once again 7+1+1)

Can you please help me find out where the error lies? I know there's been many Fibonacci-alike threads already (and I tried to follow the advice given) but I did not find any answer to my problem.

Regards, B

BloodyMary
  • 173
  • 13

1 Answers1

2

Here's an easier way to reproduce your problem:

#!/bin/bash
foo() { echo 42; }
echo $[$foo 1]

This prints 1.

This is because $foo is not a valid variable (though there is a function by this name) so it's replaced with nothing. echo $[ 1] naturally prints 1.

To expand to the result of a function, use $(command substitution):

#!/bin/bash
foo() { echo 42; }
echo $[$(foo 1)]

This prints 42. Here it is applied to your code:

#!/bin/bash
Fibo() {
   case $1 in
     0) echo 0;;
     1) echo 1;;
     *) echo $[$[$(Fibo $[$1-1])]+$[$(Fibo $[$1-2])]] ;;
   esac
}

for (( i=0; i<=$1; i++ )); do
   Fibo $i
done

Result:

$ ./foo 10
0
1
1
2
3
5
8
13
21
34
55
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • Thanks for explaining how to get the result of a bash function. I didn't know that I'm doing it in wrong way. I followed your advice and now my code works fine (but it's slightly different than yours :) - "echo $(( $[$(Fibo $(($1-1)))] + $[$(Fibo $(($1-2)))] )) ;;". Thanks again! – BloodyMary Nov 24 '18 at 22:03
  • @BloodyMary Yours is better since `$((..))` is the modern, standard way of doing shell arithmetic evaluation. I only used `$[..]` because your original example did and cringed a little the whole time. – that other guy Nov 24 '18 at 22:20